示例#1
0
def basic_simulation(cells, force, dt=dt, T1_eps=0.04):
    while True:
        cells.mesh, number_T1 = cells.mesh.transition(T1_eps)
        F = force(cells) / viscosity
        expansion = 0.05 * np.average(F * cells.mesh.vertices, 1) * dt
        dv = dt * model.sum_vertices(cells.mesh.edges, F)
        cells.mesh = cells.mesh.moved(dv).scaled(1.0 + expansion)
        yield cells
示例#2
0
def simulation_with_division(
        cells,
        force,
        dt=dt,
        T1_eps=T1_eps,
        lifespan=100.0,
        rand=None):  #(cells,force,dt=0.001,T1_eps=0.04,lifespan=100.0,rand=Non
    properties = cells.properties
    properties[
        'parent'] = cells.mesh.face_ids  #save the ids to control division parents-daugthers
    properties['ageingrate'] = np.random.normal(
        1.0 / lifespan, 0.2 / lifespan,
        len(cells))  #degradation rate per each cell
    properties['ids_division'] = [
    ]  #save ids of the cell os the division when it's ready per each time step
    properties['force_x'] = []
    properties['force_y'] = []
    properties['T1_angle_pD'] = []
    properties['Division_angle_pD'] = []
    expansion = np.array([0.0, 0.0])
    while True:
        #cells id where is true the division conditions: living cells & area greater than 2 & age cell in mitosis
        ready = np.where(~cells.empty() & (cells.mesh.area >= A_c)
                         & (cells.properties['age'] >= (t_G1 + t_S + t_G2)))[0]
        if len(
                ready
        ):  #these are the cells ready to undergo division at the current timestep
            properties['ageingrate'] = np.append(
                properties['ageingrate'],
                np.abs(
                    np.random.normal(1.0 / lifespan, 0.2 / lifespan,
                                     2 * len(ready))))
            properties['age'] = np.append(properties['age'],
                                          np.zeros(2 * len(ready)))
            properties['parent'] = np.append(
                properties['parent'],
                np.repeat(properties['parent'][ready],
                          2))  # Daugthers and parent have the same ids
            properties['ids_division'] = ready
            edge_pairs = [
                division_axis(cells.mesh, cell_id, rand) for cell_id in ready
            ]  #New edges after division
            cells.mesh = cells.mesh.add_edges(
                edge_pairs)  #Add new edges in the mesh
            for i in range(len(ready)):
                commun_edges = np.intersect1d(
                    cells.mesh.length[np.where(
                        cells.mesh.face_id_by_edge == (cells.mesh.n_face - 2 *
                                                       (i + 1)))[0]],
                    cells.mesh.length[np.where(
                        cells.mesh.face_id_by_edge == (cells.mesh.n_face - 1 -
                                                       2 * i))[0]])
                division_new_edge = np.where(
                    cells.mesh.length == np.max(commun_edges))[0]
                properties['Division_angle_pD'] = np.append(
                    properties['Division_angle_pD'],
                    cells.mesh.edge_angle[division_new_edge][0])
        properties['age'] = properties['age'] + dt * properties[
            'ageingrate']  #add time step depending of the degradation rate
        """Calculate z nuclei position (Apical-Basal movement), depending of the cell cycle phase time and age of the cell"""
        N_G1 = 1 - 1.0 / t_G1 * properties['age']  #nuclei position in G1 phase
        N_S = 0
        N_G2 = 1.0 / (t_G2) * (properties['age'] - (t_G1 + t_S)
                               )  #nuclei position in G2 and S phase
        properties['zposn'] = np.minimum(
            1.0, np.maximum(N_G1, np.maximum(N_S, N_G2)))
        """Target area function depending age and z nuclei position"""
        properties['A0'] = (properties['age'] +
                            1.0) * 0.5 * (1.0 + properties['zposn']**2)

        #############BAETTI VID

        #ath BAETTI D VID
        cells.mesh, number_T1, d = cells.mesh.transition(
            T1_eps)  #check edges verifing T1 transition
        if len(number_T1) > 0:
            for ii in number_T1:
                index = cells.mesh.face_id_by_edge[ii]
                properties['T1_angle_pD'] = np.append(
                    properties['T1_angle_pD'], cells.mesh.edge_angle[ii])
        F = force(
            cells
        ) / viscosity  #force per each cell force= targetarea+Tension+perimeter+pressure_boundary

        #EG BAETTI VID
        len_modified = np.matrix.copy(cells.mesh.length)
        #len_modified[np.where((properties['parent_group'][cells.mesh.face_id_by_edge]==1) & np.logical_not(properties['parent_group'][cells.mesh.face_id_by_edge[cells.mesh.edges.reverse]]==0))]*=0.12

        tens = (0.5 * cells.by_edge('Lambda', 'Lambda_boundary') /
                len_modified) * cells.mesh.edge_vect
        tens = tens - tens.take(cells.mesh.edges.prev, 1)
        F += tens

        dv = dt * model.sum_vertices(
            cells.mesh.edges,
            F)  #movement of the vertices using eq: viscosity*dv/dt = F
        properties['force_x'] = F[0] * viscosity
        properties['force_y'] = F[1] * viscosity

        if hasattr(cells.mesh.geometry, 'width'):
            expansion[0] = expansion_constant * np.average(
                F[0] *
                cells.mesh.vertices[0]) * dt / (cells.mesh.geometry.width**2)
        if hasattr(cells.mesh.geometry,
                   'height'):  #Cylinder mesh doesn't have 'height' argument
            expansion[1] = np.average(F[1] * cells.mesh.vertices[1]) * dt / (
                cells.mesh.geometry.height**2)
        cells.mesh = cells.mesh.moved(dv).scaled(1.0 + expansion)
        yield cells
示例#3
0
def simulation_with_division_clone_differenciation_3stripes(
        cells,
        force,
        dt=dt,
        T1_eps=T1_eps,
        lifespan=100.0,
        rand=None):  #(cells,force,dt=0.001,T1_eps=0.04,lifespan=100.0,rand=Non

    properties = cells.properties
    properties[
        'parent'] = cells.mesh.face_ids  #save the ids to control division parents-daugthers
    properties['ageingrate'] = np.random.normal(
        1.0 / lifespan, 0.2 / lifespan,
        len(cells))  #degradation rate per each cell
    #floor plate cells
    no = len(
        properties['ageingrate'][np.where(properties['parent_group'] == 3)])
    properties['ageingrate'][np.where(
        properties['parent_group'] == 3)] = np.random.normal(
            0.5 / lifespan, 0.1 / lifespan, no)

    properties['ids_division'] = [
    ]  #save ids of the cell os the division when it's ready per each time step
    properties['ids_division_1'] = [
    ]  #save ids of the cell os the division when it's ready per each time step and region
    properties['ids_division_02'] = [
    ]  #save ids of the cell os the division when it's ready per each time step and region
    properties['poisoned'] = np.zeros(
        len(cells))  ### to add diferenciation rate in PMN
    # properties['differentiation_rate']= np.zeros(len(cells),dtype=int)
    properties['force_x'] = []
    properties['force_y'] = []
    properties['T1_angle_pMN'] = []
    properties['T1_angle_pD'] = []
    properties['Division_angle_pMN'] = []
    properties['Division_angle_pD'] = []
    properties['deleted_edges'] = []
    properties['edges_division'] = []
    properties['T1_edge'] = []
    expansion = np.array([0.0, 0.0])
    while True:
        #cells id where is true the division conditions: living cells & area greater than 2 & age cell in mitosis
        ready = np.where(
            (~cells.empty() & (cells.mesh.area >= A_c)
             & (cells.properties['age'] >= (t_G1 + t_S + t_G2)))
            | (~cells.empty() & (cells.properties['parent_group'] == 3)
               & (cells.mesh.area >= 0.4)
               & (cells.properties['age'] >= (t_G1 + t_S + t_G2))))[0]

        if len(
                ready
        ):  #these are the cells ready to undergo division at the current timestep
            #properties['ageingrate'] =np.append(properties['ageingrate'], np.repeat(properties['ageingrate'][ready],2))
            properties['age'] = np.append(properties['age'],
                                          np.zeros(2 * len(ready)))
            properties['parent'] = np.append(
                properties['parent'],
                np.repeat(properties['parent'][ready],
                          2))  # Daugthers and parent have the same ids
            properties['ids_division'] = ready
            properties['parent_group'] = np.append(
                properties['parent_group'],
                np.repeat(properties['parent_group'][ready],
                          2))  #use to draw clones

            properties['poisoned'] = np.append(
                properties['poisoned'], np.zeros(
                    2 * len(ready)))  ### to add diferenciation rate in PMN
            edge_pairs = [
                division_axis(cells.mesh, cell_id, rand) for cell_id in ready
            ]  #New edges after division
            properties['edges_division'].append(edge_pairs)
            cells.mesh = cells.mesh.add_edges(
                edge_pairs)  #Add new edges in the mesh

            for i in range(len(ready)):
                commun_edges = np.intersect1d(
                    cells.mesh.length[np.where(
                        cells.mesh.face_id_by_edge == (cells.mesh.n_face - 2 *
                                                       (i + 1)))[0]],
                    cells.mesh.length[np.where(
                        cells.mesh.face_id_by_edge == (cells.mesh.n_face - 1 -
                                                       2 * i))[0]])
                division_new_edge = np.where(
                    cells.mesh.length == np.max(commun_edges))[0]
                if properties['parent_group'][ready[i]] == 3:
                    properties['ageingrate'] = np.append(
                        properties['ageingrate'],
                        np.abs(
                            np.random.normal(1.0 / lifespan, 0.2 / lifespan,
                                             2)))
                else:
                    properties['ageingrate'] = np.append(
                        properties['ageingrate'],
                        np.abs(
                            np.random.normal(1.0 / lifespan, 0.2 / lifespan,
                                             2)))
                # print len(properties['ageingrate'])
                #if properties['parent_group'][cells.mesh.n_face-2*(i+1)]==1:
                #   properties['Division_angle_pMN']= np.append(properties['Division_angle_pMN'],cells.mesh.edge_angle[division_new_edge][0])
                #else:
                #   properties['Division_angle_pD']= np.append(properties['Division_angle_pD'],cells.mesh.edge_angle[division_new_edge][0])
            #for ids in ready:
            #   if properties['parent_group'][ids]==1:
            #      properties['ids_division_1'] = np.append(properties['ids_division_1'], ids)
            # else:
            #    properties['ids_division_02'] = np.append(properties['ids_division_02'], ids)
        ###### Differentiation rate
        properties['differentiation_rate'] = time_hours * dt * (np.array([
            0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0
        ]))[properties['parent_group']]  #Used 0.02, 0.0002 & 1/13
        properties['poisoned'] = properties['poisoned'] - (
            properties['poisoned'] -
            1) * (~(cells.empty()) &
                  (rand.rand(len(cells)) < properties['differentiation_rate']))
        properties['age'] = properties['age'] + dt * properties[
            'ageingrate']  #add time step depending of the degradation rate

        N_G1 = 1 - 1.0 / t_G1 * properties['age']  #nuclei position in G1 phase
        N_S = 0
        N_G2 = 1.0 / (t_G2) * (properties['age'] - (t_G1 + t_S)
                               )  #nuclei position in G2 and S phase
        properties['zposn'] = np.minimum(
            1.0, np.maximum(N_G1, np.maximum(N_S, N_G2)))
        properties['zposn'][np.where(properties['parent_group'] == 3)] = 0
        """Target area function depending age and z nuclei position"""
        properties['A0'] = (properties['age'] + 1.0) * 0.5 * (
            1.0 + properties['zposn']**2) * (1.0 -
                                             cells.properties['poisoned'])

        cells.mesh, number_T1, del_edges = cells.mesh.transition(T1_eps)

        properties['deleted_edges'].append(del_edges)
        #if len(number_T1)>0:
        #   for ii in number_T1:
        #      properties['T1_edge']=np.append(properties['T1_edge'], ii)
        # index = cells.mesh.face_id_by_edge[ii]
        #if properties['parent_group'][index]==1:
        #   properties['T1_angle_pMN'] =np.append(properties['T1_angle_pMN'],cells.mesh.edge_angle[ii])
        #else:
        #   properties['T1_angle_pD'] =np.append(properties['T1_angle_pD'],cells.mesh.edge_angle[ii])
        F = force(
            cells
        ) / viscosity  #force per each cell force= targetarea+Tension+perimeter+pressure_boundary

        #ADDING THE FLOOR PLATE
        len_modified = np.matrix.copy(cells.mesh.length)
        #this next line can be use for modifying all edges at the boundary
        #len_modified[np.where( ((properties['parent_group'][cells.mesh.face_id_by_edge]==3) & np.logical_not(properties['parent_group'][cells.mesh.face_id_by_edge[cells.mesh.edges.reverse]]==3)) | ((properties['parent_group'][cells.mesh.face_id_by_edge]==2) & (properties['parent_group'][cells.mesh.face_id_by_edge[cells.mesh.edges.reverse]]==3)) | ((properties['parent_group'][cells.mesh.face_id_by_edge]==4) & (properties['parent_group'][cells.mesh.face_id_by_edge[cells.mesh.edges.reverse]]==3)) )]*=0.004

        #modifying tension w.r.t. area
        for n in np.where(
            ((properties['parent_group'][cells.mesh.face_id_by_edge] == 3)
             & np.logical_not(
                 properties['parent_group'][cells.mesh.face_id_by_edge[
                     cells.mesh.edges.reverse]] == 3)))[0]:
            if abs(cells.mesh.area[cells.mesh.face_id_by_edge[n]] -
                   cells.mesh.area[cells.mesh.face_id_by_edge[
                       cells.mesh.edges.reverse[n]]]) > 0.4:
                len_modified[n] *= 0.002

        tens = (0.5 * cells.by_edge('Lambda', 'Lambda_boundary') /
                len_modified) * cells.mesh.edge_vect
        tens = tens - tens.take(cells.mesh.edges.prev, 1)
        F += tens

        dv = dt * model.sum_vertices(
            cells.mesh.edges,
            F)  #movement of the vertices using eq: viscosity*dv/dt = F
        #properties['force_x'] = F[0]*viscosity
        #properties['force_y'] = F[1]*viscosity
        if hasattr(cells.mesh.geometry, 'width'):
            expansion[0] = expansion_constant * np.average(
                F[0] *
                cells.mesh.vertices[0]) * dt / (cells.mesh.geometry.width**2)
        if hasattr(cells.mesh.geometry,
                   'height'):  #Cylinder mesh doesn't have 'height' argument
            expansion[1] = np.average(F[1] * cells.mesh.vertices[1]) * dt / (
                cells.mesh.geometry.height**2)
        cells.mesh = cells.mesh.moved(dv).scaled(1.0 + expansion)

        yield cells
示例#4
0
def simulation_with_division_clone_whole_tissue_differenciation(
        cells,
        force,
        dt=dt,
        T1_eps=T1_eps,
        lifespan=100.0,
        rand=None
):  #(cells,force,dt=0.001,T1_eps=0.04,lifespan=100.0,rand=None
    properties = cells.properties
    properties[
        'parent'] = cells.mesh.face_ids  #save the ids to control division parents-daugthers
    properties['ageingrate'] = np.random.normal(
        1.0 / lifespan, 0.2 / lifespan,
        len(cells))  #degradation rate per each cell
    properties['ids_division'] = [
    ]  #save ids of the cell os the division when it's ready per each time step
    properties['ids_division_1'] = [
    ]  #save ids of the cell os the division when it's ready per each time step and region
    properties['ids_division_02'] = [
    ]  #save ids of the cell os the division when it's ready per each time step and region
    properties['poisoned'] = np.zeros(
        len(cells))  ### to add diferenciation rate in PMN
    # properties['differentiation_rate']= np.zeros(len(cells),dtype=int)
    properties['force_x'] = []
    properties['force_y'] = []
    properties['T1_angle_pMN'] = []
    properties['T1_angle_pD'] = []
    properties['Division_angle_pMN'] = []
    properties['Division_angle_pD'] = []
    properties['ids_removed'] = []
    expansion = np.array([0.0, 0.0])
    while True:
        #cells id where is true the division conditions: living cells & area greater than 2 & age cell in mitosis
        ready = np.where(~cells.empty() & (cells.mesh.area >= A_c)
                         & (cells.properties['age'] >= (t_G1 + t_S + t_G2)))[0]
        if len(
                ready
        ):  #these are the cells ready to undergo division at the current timestep
            properties['ageingrate'] = np.append(
                properties['ageingrate'],
                np.abs(
                    np.random.normal(1.0 / lifespan, 0.2 / lifespan,
                                     2.0 * len(ready))))
            properties['age'] = np.append(properties['age'],
                                          np.zeros(2 * len(ready)))
            properties['parent'] = np.append(
                properties['parent'],
                np.repeat(properties['parent'][ready],
                          2))  # Daugthers and parent have the same ids
            properties['ids_division'] = ready
            properties['parent_group'] = np.append(
                properties['parent_group'],
                np.repeat(properties['parent_group'][ready],
                          2))  #use to draw clones
            properties['poisoned'] = np.append(
                properties['poisoned'], np.zeros(
                    2 * len(ready)))  ### to add diferenciation rate in PMN
            # properties['differentiation_rate'] = np.append(properties['differentiation_rate'], diff_rate_hours*np.ones(2*len(ready)))
            edge_pairs = [
                division_axis(cells.mesh, cell_id, rand) for cell_id in ready
            ]  #New edges after division
            cells.mesh = cells.mesh.add_edges(
                edge_pairs)  #Add new edges in the mesh
            for i in range(len(ready)):
                commun_edges = np.intersect1d(
                    cells.mesh.length[np.where(
                        cells.mesh.face_id_by_edge == (cells.mesh.n_face - 2 *
                                                       (i + 1)))[0]],
                    cells.mesh.length[np.where(
                        cells.mesh.face_id_by_edge == (cells.mesh.n_face - 1 -
                                                       2 * i))[0]])
                division_new_edge = np.where(
                    cells.mesh.length == np.max(commun_edges))[0]
                if properties['parent_group'][cells.mesh.n_face - 2 *
                                              (i + 1)] == 1:
                    properties['Division_angle_pMN'] = np.append(
                        properties['Division_angle_pMN'],
                        cells.mesh.edge_angle[division_new_edge][0])
                else:  #antes estaba mal y ponia pD!!!! las simulaciones guardadas estan mal
                    properties['Division_angle_pMN'] = np.append(
                        properties['Division_angle_pMN'],
                        cells.mesh.edge_angle[division_new_edge][0])
            for ids in ready:
                if properties['parent_group'][ids] == 1:
                    properties['ids_division_1'] = np.append(
                        properties['ids_division_1'], ids)
                else:  #antes estaba mal y ponia 0_2!!!! las simulaciones guardadas estan mal
                    properties['ids_division_1'] = np.append(
                        properties['ids_division_1'], ids)
        ###### Defferentiation rate
        properties['differentiation_rate'] = time_hours * dt * (np.array([
            0.0, diff_rate_hours, 0.0, 0.0, 0.0, diff_rate_hours, 0.0
        ]))[properties['parent_group']]  #Used 0.02, 0.0002 & 1/13
        properties['poisoned'] = properties['poisoned'] - (
            properties['poisoned'] -
            1) * (~(cells.empty()) &
                  (rand.rand(len(cells)) < properties['differentiation_rate']))
        properties['age'] = properties['age'] + dt * properties[
            'ageingrate']  #add time step depending of the degradation rate

        N_G1 = 1 - 1.0 / t_G1 * properties['age']  #nuclei position in G1 phase
        N_S = 0
        N_G2 = 1.0 / (t_G2) * (properties['age'] - (t_G1 + t_S)
                               )  #nuclei position in G2 and S phase
        properties['zposn'] = np.minimum(
            1.0, np.maximum(N_G1, np.maximum(N_S, N_G2)))
        """Target area function depending age and z nuclei position"""
        properties['A0'] = (properties['age'] + 1.0) * 0.5 * (
            1.0 + properties['zposn']**2) * (1.0 -
                                             cells.properties['poisoned'])

        cells.mesh, number_T1, ids_removed = cells.mesh.transition(T1_eps)

        properties['ids_removed'].append(ids_removed)  #####BAETTI VID
        if len(number_T1) > 0:
            for ii in number_T1:
                index = cells.mesh.face_id_by_edge[ii]
                if properties['parent_group'][index] == 1:
                    properties['T1_angle_pMN'] = np.append(
                        properties['T1_angle_pMN'], cells.mesh.edge_angle[ii])
                else:  #antes estaba mal y ponia pD!!!! las simulaciones guardadas estan mal
                    properties['T1_angle_pMN'] = np.append(
                        properties['T1_angle_pMN'], cells.mesh.edge_angle[ii])
        F = force(
            cells
        ) / viscosity  #force per each cell force= targetarea+Tension+perimeter+pressure_boundary
        dv = dt * model.sum_vertices(
            cells.mesh.edges,
            F)  #movement of the vertices using eq: viscosity*dv/dt = F
        properties['force_x'] = F[0] * viscosity
        properties['force_y'] = F[1] * viscosity

        if hasattr(cells.mesh.geometry, 'width'):
            expansion[0] = expansion_constant * np.average(
                F[0] *
                cells.mesh.vertices[0]) * dt / (cells.mesh.geometry.width**2)
        if hasattr(cells.mesh.geometry,
                   'height'):  #Cylinder mesh doesn't have 'height' argument
            expansion[1] = np.average(F[1] * cells.mesh.vertices[1]) * dt / (
                cells.mesh.geometry.height**2)
        cells.mesh = cells.mesh.moved(dv).scaled(1.0 + expansion)
        yield cells
示例#5
0
def simulation_with_division_clone_differentiation(
        cells,
        force,
        dt=dt,
        T1_eps=T1_eps,
        lifespan=100.0,
        rand=None):  #(cells,force,dt=0.001,T1_eps=0.04,lifespan=100.0,rand=Non
    properties = cells.properties
    properties[
        'parent'] = cells.mesh.face_ids  #save the ids to control division parents-daugthers
    properties['ageingrate'] = np.random.normal(
        1.0 / lifespan, 0.2 / lifespan,
        len(cells))  #degradation rate per each cell
    properties['ids_division'] = [
    ]  #save ids of the cell os the division when it's ready per each time step
    properties['poisoned'] = np.zeros(
        len(cells))  ### to add diferenciation rate in PMN

    expansion = np.array([0.0, 0.0])
    while True:
        #cells id where is true the division conditions: living cells & area greater than 2 & age cell in mitosis
        ready = np.where(~cells.empty() & (cells.mesh.area >= A_c)
                         & (cells.properties['age'] >= (t_G1 + t_S + t_G2)))[0]
        if len(
                ready
        ):  #these are the cells ready to undergo division at the current timestep
            properties['ageingrate'] = np.append(
                properties['ageingrate'],
                np.abs(
                    np.random.normal(1.0 / lifespan, 0.2 / lifespan,
                                     2.0 * len(ready))))
            properties['age'] = np.append(properties['age'],
                                          np.zeros(2 * len(ready)))
            properties['parent'] = np.append(
                properties['parent'],
                np.repeat(properties['parent'][ready],
                          2))  # Daugthers and parent have the same ids
            properties['ids_division'] = ready
            properties['parent_group'] = np.append(
                properties['parent_group'],
                np.repeat(properties['parent_group'][ready],
                          2))  #use to draw clones
            properties['poisoned'] = np.append(
                properties['poisoned'], np.zeros(
                    2 * len(ready)))  ### to add diferenciation rate in PMN
            edge_pairs = [
                division_axis(cells.mesh, cell_id, rand) for cell_id in ready
            ]  #New edges after division
            cells.mesh = cells.mesh.add_edges(
                edge_pairs)  #Add new edges in the mesh
        ###### Defferenciation rate
        properties['poisoned'] = properties['poisoned'] - (
            properties['poisoned'] -
            1) * (~(cells.empty()) & (rand.rand(len(cells)) <
                                      (dt * diff_rate_hours * time_hours)))
        properties['age'] = properties['age'] + dt * properties[
            'ageingrate']  #add time step depending of the degradation rate
        """Calculate z nuclei position (Apical-Basal movement), depending of the cell cycle phase time and age of the cell"""
        N_G1 = 1 - 1.0 / t_G1 * properties['age']  #nuclei position in G1 phase
        N_S = 0
        N_G2 = 1.0 / (t_G2) * (properties['age'] - (t_G1 + t_S)
                               )  #nuclei position in G2 and S phase
        properties['zposn'] = np.minimum(
            1.0, np.maximum(N_G1, np.maximum(N_S, N_G2)))
        """Target area function depending age and z nuclei position"""
        properties['A0'] = (properties['age'] + 1.0) * 0.5 * (
            1.0 + properties['zposn']**2) * (1.0 -
                                             cells.properties['poisoned'])

        cells.mesh, number_T1 = cells.mesh.transition(
            T1_eps)  #check edges verifing T1 transition
        F = force(
            cells
        ) / viscosity  #force per each cell force= targetarea+Tension+perimeter+pressure_boundary
        dv = dt * model.sum_vertices(
            cells.mesh.edges,
            F)  #movement of the vertices using eq: viscosity*dv/dt = F

        if hasattr(cells.mesh.geometry, 'width'):
            expansion[0] = expansion_constant * np.average(
                F[0] *
                cells.mesh.vertices[0]) * dt / (cells.mesh.geometry.width**2)
        if hasattr(cells.mesh.geometry,
                   'height'):  #Cylinder mesh doesn't have 'height' argument
            expansion[1] = np.average(F[1] * cells.mesh.vertices[1]) * dt / (
                cells.mesh.geometry.height**2)
        cells.mesh = cells.mesh.moved(dv).scaled(1.0 + expansion)
        yield cells