###
# cGrid2D.py (C) of thesis research "Modeling and Simulating Three Phases of Steel: Austenite, Feritte and Cementite" 2018 by Thijs Verbeek
# is licensed under a Creative Commons Attribution-NonCommercial-ShareAlike 4.0 International License.
#
# You should have received a copy of the license along with this
# work. If not, see <http://creativecommons.org/licenses/by-nc-sa/4.0/>.
###

import numpy as np
from scipy.spatial import Delaunay
from scipy.sparse import lil_matrix
from scipy.sparse import coo_matrix
from scipy.sparse import csr_matrix
from scipy.sparse import hstack, vstack
import scipy.linalg as la

from Grid import cMesh
from Grid import cLevel_Set



class cGrid:
    def __init__(self, N, x0, y0, xN, yN, init_distribution, dimension, interface_gammaalpha0, interface_alphatheta0, mesh = None, two_particles = None, delta = 0.3):
        self.two_particles = two_particles
        self.x0 = x0
        self.xN = xN
        self.y0 = y0
        self.yN = yN
        self.d = dimension
        #delta = 1/2, interface always put on a grid point. delta = 0, interface always own point.
        self.delta = delta
        self.prefix_dim = 0
        ### This code is made for dimension = 2
        if dimension == 2:
            self.interface_gammaalpha = cMesh.cMesh(-1,dimension,'Interface austenite/ferrite')
            self.interface_alphatheta = cMesh.cMesh(-1,dimension,'Interface ferrite/austenite')
            self.interface_gammatheta = cMesh.cMesh(-1,dimension,'Interface ferrite/austenite')
            self.interface_gammaalpha0 = interface_gammaalpha0
            self.interface_alphatheta0 = interface_alphatheta0
            ### For ellipse with parameters as in thesis
            x03 = (10+np.array([4.0, 4.6])) * 10**(-self.prefix_dim)
            t0 = 5*np.pi/12
            self.a_t = (x03[0] - interface_alphatheta0[0])/np.cos(t0)
            self.b_t = (x03[1] - interface_alphatheta0[1])/np.sin(t0)
            omega_t0 = np.arctan(self.b_t*np.cos(t0)/(-self.a_t*np.sin(t0)))
#            omega = -np.arccos((1.05 - .94)/.39)
#            t0_ga = np.arctan(-np.cos(omega_t0 + omega)/(x03[0] - interface_gammaalpha0[0]))
            omega = np.arccos((1.05 - .94)/.39)
            self.a_ga = 1.39 * (x03[0] - interface_alphatheta0[0])
            t0_ga = np.arccos((x03[0] - interface_gammaalpha0[0])/self.a_ga)
            self.b_ga = - self.a_ga * np.tan(np.pi - omega - omega_t0) * np.tan(t0_ga)
#            self.b_ga =   self.a_ga
#            self.a_ga = ((x03[0] - interface_gammaalpha0[0])/np.cos(t0_ga))
#            self.b_ga = np.abs((x03[1] - interface_gammaalpha0[1])/np.sin(t0_ga))
        ### if mesh is not preloaded 
        if mesh == None:
            self.N = N
            self.background_mesh = cMesh.cMesh(self.N,dimension,'Background mesh')
            self.points, self.background_mesh.is_point_BP = cGrid.get_points(self.N, x0, y0, xN, yN, init_distribution, dimension)
        else:
            self.points = mesh['p'].T * 10**(-self.prefix_dim)
            self.N = len(self.points)
            self.background_mesh = cMesh.cMesh(self.N,dimension,'Background mesh')
            self.background_mesh.is_point_BP = np.zeros((self.N,2),dtype = np.int)
            i = 0
            for p in self.points:
                # (#edges, 2) stores: [0] : 1 if boundary edge, 0 if not, [1] 1: bottom, 2:right, 3:upper, 4:left, 0:not boundary point
                if p[0] == x0:
                    self.background_mesh.is_point_BP[i] = [1,4]
                if p[0] == xN:
                    self.background_mesh.is_point_BP[i] = [1,2]
                if p[1] == y0:
                    self.background_mesh.is_point_BP[i] = [1,1]
                if p[1] == yN:
                    self.background_mesh.is_point_BP[i] = [1,3]
                #cornerpoint 5
                if p[0] == x0 and p[1] == y0 or p[0] == xN and p[1]== y0 or p[0] == x0 and p[1] == yN or p[0] == xN and p[1] == yN:
                    self.background_mesh.is_point_BP[i,1] = 5
                i = i+1

        self.background_mesh.points = self.points.copy()
        self.enriched_mesh = cMesh.cMesh(self.N,dimension, 'Enriched mesh')
        self.enriched_mesh.points = self.points.copy()
        self.enriched_mesh.points_index = np.arange(0,self.N)
        self.enriched_mesh.n = self.N
        self.diffusion_mesh_gamma = cMesh.cMesh(self.N,dimension, r'Diffusion mesh $\gamma$')
        self.diffusion_mesh_alpha = cMesh.cMesh(self.N,dimension, r'Diffusion mesh $\alpha$')
        self.precipitate_mesh_theta = cMesh.cMesh(self.N,dimension, r'Diffusion mesh $\theta$')
        self.gamma_dissolved = 0
        self.theta_dissolved = 0
        self.alpha_dissolved = 0

        self.grid(mesh)





    @staticmethod
    def get_points(N, x0, y0, xN, yN, init_distribution, d):
        is_point_BP = np.zeros((N,2),dtype = np.int)
        if init_distribution == 'random':
            if d==2:
                N_intern = int(((N-1)**(1/2)-2)**2+1)
                N_boundary = N - N_intern
                points_intern = np.random.uniform(x0,xN,[N_intern, 2])
                if N_boundary/4 - int(N_boundary/4) != 0:
                    print('boundary elements cant be divided by 4')
                points_boundary_bottom = np.hstack((np.random.uniform(x0,xN,[int(N_boundary/4-1), 1]), y0*np.ones((int(N_boundary/4-1),1))))
                points_boundary_up     = np.hstack((np.random.uniform(x0,xN,[int(N_boundary/4-1), 1]), yN*np.ones((int(N_boundary/4-1),1))))
                points_boundary_left   = np.hstack((x0*np.ones((int(N_boundary/4-1),1)), np.random.uniform(x0,xN,[int(N_boundary/4-1), 1])))
                points_boundary_right  = np.hstack((xN*np.ones((int(N_boundary/4-1),1)), np.random.uniform(x0,xN,[int(N_boundary/4-1), 1])))
                points_boundary = np.concatenate((points_boundary_bottom, points_boundary_up, points_boundary_left, points_boundary_right,
                                      np.array([x0,y0]).reshape(1,2),np.array([x0,yN]).reshape(1,2),np.array([xN,y0]).reshape(1,2),np.array([xN,yN]).reshape(1,2)),axis=0)

                points = np.vstack((points_intern,points_boundary))
                NN0 = 0
                NN1 = len(points_boundary_bottom)
                is_point_BP[N_intern + NN0 : N_intern + NN1] = np.hstack((np.ones((NN1-NN0,1), dtype = np.int), np.ones((NN1-NN0,1), dtype = np.int)))
                NN0 = NN0 + len(points_boundary_bottom)
                NN1 = NN1 + len(points_boundary_up)
                is_point_BP[N_intern + NN0 : N_intern + NN1] = np.hstack((np.ones((NN1-NN0,1), dtype = np.int), 3*np.ones((NN1-NN0,1), dtype = np.int)))
                NN0 = NN0 + len(points_boundary_up)
                NN1 = NN1 + len(points_boundary_left)
                is_point_BP[N_intern + NN0 : N_intern + NN1] = np.hstack((np.ones((NN1-NN0,1), dtype = np.int), 4*np.ones((NN1-NN0,1), dtype = np.int)))
                NN0 = NN0 + len(points_boundary_left)
                NN1 = NN1 + len(points_boundary_right)
                is_point_BP[N_intern + NN0 : N_intern + NN1] = np.hstack((np.ones((NN1-NN0,1), dtype = np.int), 2*np.ones((NN1-NN0,1), dtype = np.int)))
                is_point_BP[N_intern + N_boundary-4 : N_intern + N_boundary,0] = 1
                is_point_BP[N_intern + N_boundary-4 : N_intern + N_boundary,1] = 5
        elif init_distribution == 'uniform':
            if d == 2:
                # uniform grid needs a little offset to get a proper grid
                offset = 1e-5

                xx = np.linspace(x0, xN, N**(1/2))
                yy = np.linspace(x0, xN, N**(1/2))
                XX,YY = np.meshgrid(xx,yy)
                points = np.zeros((N,2))
                k = 0
                for i in range(0,len(xx)):
                    for j in range(0,len(yy)):
                        if XX[i,j] != x0 and XX[i,j] != xN and YY[i,j] != y0 and YY[i,j] != yN:
                            new_point = [[XX[i,j] + offset*(2*np.random.rand()-1) , YY[i,j] + offset*(2*np.random.rand()-1)]]
                        else:
                            new_point = [[XX[i,j] , YY[i,j]]]
                            # (#edges, 2) stores: [0] : 1 if boundary edge, 0 if not, [1] 1: bottom, 2:right, 3:upper, 4:left, 0:not boundary edge
                            if XX[i,j] == x0:
                                is_point_BP[k] = [1,4]
                            if XX[i,j] == xN:
                                is_point_BP[k] = [1,2]
                            if YY[i,j] == y0:
                                is_point_BP[k] = [1,1]
                            if YY[i,j] == yN:
                                is_point_BP[k] = [1,3]
                            #cornerpoint
                            if XX[i,j] == x0 and YY[i,j] == y0 or XX[i,j] == xN and YY[i,j] == y0 or XX[i,j] == x0 and YY[i,j] == yN or XX[i,j] == xN and YY[i,j] == yN:
                                is_point_BP[k,1] = 5
                        points[[k],:] = new_point
                        k=k+1
                points_intern = []
                points_boundary = []
        return points, is_point_BP




    def grid(self, mesh):
        if self.d == 2:
            if mesh == None:
                self.background_mesh.edges = -1
                self.background_mesh.triangles = -1

                self.I_diff = -1
                self.I_prec = -1


                #Define background mesh T with coarseness h
                self.triangles_object = Delaunay(self.points)
                self.background_mesh.triangles_points_index = self.triangles_object.simplices
                self.background_mesh.triangles = self.points[self.background_mesh.triangles_points_index]
                self.background_mesh.area_triangle = -np.ones(self.background_mesh.triangles_points_index.shape[0])
                self.background_mesh.n_tri = len(self.background_mesh.triangles)
                self.enriched_mesh.triangles_points_index = self.background_mesh.triangles_points_index.copy()
                self.enriched_mesh.n_tri = self.background_mesh.n_tri
                self.has_point_been_shifted = -np.ones((self.N, 2), dtype = np.int)
            else:
                self.background_mesh.edges_index = -1
                self.background_mesh.edges = -1
                self.background_mesh.triangles_points_index = mesh['triangles'].astype(np.int).T - 1
                self.background_mesh.triangles = self.background_mesh.points[self.background_mesh.triangles_points_index]

                self.background_mesh.n_tri = len(self.background_mesh.triangles_points_index)
                self.enriched_mesh.triangles_points_index = self.background_mesh.triangles_points_index.copy()
                self.enriched_mesh.n_tri = self.background_mesh.n_tri
                self.has_point_been_shifted = -np.ones((self.N, 2), dtype = np.int)
                self.background_mesh.area_triangle = -np.ones(self.background_mesh.n_tri)

                self.I_diff = -1
                self.I_prec = -1

            self.diffusion_mesh_gamma.enriched_to_gamma = np.zeros(0,dtype = np.int)
            self.diffusion_mesh_alpha.enriched_to_alpha = np.zeros(0,dtype = np.int)


            #Define initial level-set function phi0 on T
            if self.two_particles == None:
                self.level_set_gammaalpha_enriched = cLevel_Set.cLevel_Set(self.enriched_mesh.n,self.d,self.enriched_mesh.points,0, self.interface_gammaalpha0, 'ga', self.a_ga, self.b_ga, which_phi =  1)
            else:
                self.level_set_gammaalpha_enriched = cLevel_Set.cLevel_Set(self.enriched_mesh.n,self.d,self.enriched_mesh.points,0, self.interface_gammaalpha0, 'ga', self.a_ga, self.b_ga, which_phi =  1)
                self.level_set_gammaalpha_enriched1 = cLevel_Set.cLevel_Set(self.enriched_mesh.n,self.d,self.enriched_mesh.points,0, np.hstack((self.interface_gammaalpha0[0], self.interface_gammaalpha0[1] - 2 * (self.interface_gammaalpha0[1] - 10))), 'ga1', self.a_ga, self.b_ga, which_phi =  1)
                self.level_set_gammaalpha_enriched2 = cLevel_Set.cLevel_Set(self.enriched_mesh.n,self.d,self.enriched_mesh.points,0, self.interface_gammaalpha0, 'ga2', self.a_ga, self.b_ga, which_phi =  13)
                i = 0
                for p in self.background_mesh.points:
                    if p[1] > self.interface_gammaalpha0[1]:
                        pass #stays self.level_set_gammaalpha_enriched.phi[i]
                    elif p[1] < self.interface_gammaalpha0[1] and p[1] > self.interface_gammaalpha0[1] - 2*(self.interface_gammaalpha0[1]-10):
                        self.level_set_gammaalpha_enriched.phi[i] = self.level_set_gammaalpha_enriched2.phi[i]
                    elif p[1] < self.interface_gammaalpha0[1] - 2*(self.interface_gammaalpha0[1]-10):
                        self.level_set_gammaalpha_enriched.phi[i] = self.level_set_gammaalpha_enriched1.phi[i]
                    else:
                        print('point p in two particles not found? ', p, i)
                    i = i+1
            self.level_set_gammaalpha_enriched.phi_background = self.level_set_gammaalpha_enriched.phi.copy()
            self.level_set_alphatheta_enriched = cLevel_Set.cLevel_Set(self.enriched_mesh.n,self.d,self.enriched_mesh.points,0, self.interface_alphatheta0, 't', self.a_t, self.b_t, which_phi = 2)

            self.background_mesh.point_in_tri = lil_matrix((self.background_mesh.n, self.background_mesh.n_tri), dtype = np.int)
            self.enriched_mesh.point_in_tri = lil_matrix((self.enriched_mesh.n, self.enriched_mesh.n_tri), dtype = np.int)
            self.enriched_mesh.three_neighbours = lil_matrix((self.enriched_mesh.n, self.enriched_mesh.n), dtype = np.int)

            self.background_mesh.i_ghost_fixed = -1

            #Define interface points/edges
            self.update(0)

    ### Update mesh, update_count = 0 is at t_0, update_count 1 is with triple point handling is done in cut/cut_twice, not during the bend/shift/cut of the triple points
    ### This does sometimes result in a bad flipped edge, but smaller code and (if I remember correctly) better with indepedented shifting of the two level-set functions
    ### I think update_count = 2 can be deleted (together with the long function for triple bend/shift/cut)
    def update(self, update_count):
        patch_size = 6
        plot_steps = False


        self.diffusion_points_old_gamma = self.diffusion_mesh_gamma.points.copy()
        self.diffusion_points_old_alpha = self.diffusion_mesh_alpha.points.copy()
        self.diffusion_points_index_old_gamma = self.diffusion_mesh_gamma.points_index.copy()
        self.diffusion_points_index_old_alpha = self.diffusion_mesh_alpha.points_index.copy()
        self.diffusion_enriched_to_alpha_old = self.diffusion_mesh_alpha.enriched_to_alpha.copy()
        self.diffusion_enriched_to_gamma_old = self.diffusion_mesh_gamma.enriched_to_gamma.copy()
        self.enriched_points_old = self.enriched_mesh.points.copy()
        self.enriched_trii_old = self.enriched_mesh.triangles_points_index.copy()
        self.point_in_tri_old = self.enriched_mesh.point_in_tri.copy()
        self.has_point_been_shifted_old = self.has_point_been_shifted.copy()
        try:
            self.enriched_three_neighbours_old = self.enriched_mesh.three_neighbours.copy()
        except:
            self.enriched_three_neighbours_old = lil_matrix((self.enriched_mesh.n, self.enriched_mesh.n), dtype = np.int)

        self.background_mesh.Tau = lil_matrix((self.background_mesh.n, self.background_mesh.n+1))
        self.background_mesh.Tau_all_ga = coo_matrix((0, self.background_mesh.n))
        self.background_mesh.Tau_all_t  = coo_matrix((0, self.background_mesh.n))


        self.is_point_BP = self.background_mesh.is_point_BP.copy()

        self.enriched_mesh.area_triangle = self.background_mesh.area_triangle.copy()

        self.enriched_mesh.points = self.background_mesh.points.copy()
        self.enriched_mesh.n = self.background_mesh.n

        self.enriched_mesh.triangles_points_index = self.background_mesh.triangles_points_index.copy()
        self.enriched_mesh.triangles = self.background_mesh.triangles.copy()
        self.enriched_mesh.n_tri = self.background_mesh.n_tri

        self.precipitate_mesh_theta.points_index = -1
        self.precipitate_mesh_theta.edges = -1
        self.precipitate_mesh_theta.triangles = -1
        self.precipitate_mesh_theta.triangles_points_index = np.zeros((0,3),dtype = np.int)
        self.precipitate_mesh_theta.triangles_index = np.zeros(0,dtype = np.int)
        self.diffusion_mesh_gamma.edges = -1
        self.diffusion_mesh_gamma.triangles = -1
        self.diffusion_mesh_gamma.triangles_points_index = np.zeros((0,3),dtype = np.int)
        self.diffusion_mesh_gamma.triangles_index = np.zeros(0,dtype = np.int)
        self.diffusion_mesh_alpha.edges = -1
        self.diffusion_mesh_alpha.triangles = -1
        self.diffusion_mesh_alpha.triangles_points_index = np.zeros((0,3),dtype = np.int)
        self.diffusion_mesh_alpha.triangles_index = np.zeros(0,dtype = np.int)

        self.interface_gammaalpha.edges_index = np.zeros((0,2),dtype=np.int)
        self.interface_gammaalpha.ghost_edges_index = np.zeros((0,2),dtype=np.int)
        self.interface_gammatheta.edges_index = np.zeros((0,2),dtype=np.int)
        self.interface_alphatheta.edges_index = np.zeros((0,2),dtype=np.int)



        self.interface_gammaalpha.triple_points_index = np.zeros(0,dtype=np.int)
        self.interface_gammatheta.triple_points_index = np.zeros(0,dtype=np.int)
        self.interface_alphatheta.triple_points_index = np.zeros(0,dtype=np.int)


        self.triple_points_index = np.zeros(0, dtype = np.int)

        #Points that have been shifted on one interface can't be shifted to other interface. 1st entry says if shifted (+1), 2nd to which interface, where
        #1/11 = gammaalpha(11 = ghost points), 2 = alphatheta, 3 = gammatheta, 4 and any factor 4 is triple point (shifted triple will be 8 in order to have cut_twice work)
        self.has_point_been_shifted = -np.ones((self.N, 2), dtype = np.int) #ga 'ghost' will be changed at the end of update
        self.trii_triple = np.zeros(0, dtype =  np.int)

        #This only has to be done once, background mesh stays the same
        if update_count == 0:
            edges_i = np.zeros((0,2), dtype = int)
            i=0
            for trii in self.background_mesh.triangles_points_index:
                for edgei in np.array([[0,1],[0,2],[1,2]]):
                    edgeii = np.sort(trii[edgei])
                    edges_i = np.vstack((edges_i, edgeii))
                tri = self.background_mesh.points[trii]
                lambda_barycentric = la.solve( np.array([ [tri[0,0], tri[1,0], tri[2,0]],
                                                          [tri[0,1], tri[1,1], tri[2,1]],
                                                          [1       , 1       , 1       ] ]), np.array([ self.interface_gammaalpha0[0], self.interface_gammaalpha0[1]-self.b_ga, 1]))
                if all(lambda_barycentric >= 0) and all(lambda_barycentric <= 1):
                    triple_Tau = np.zeros(self.background_mesh.n)
                    triple_Tau[trii] = lambda_barycentric
                    self.background_mesh.Tau_fixed_ghost_point = triple_Tau
                self.background_mesh.point_in_tri[trii,i] = i+1
                i=i+1

            self.background_mesh.patch_matrix = lil_matrix((self.background_mesh.n, self.background_mesh.n))
            self.background_mesh.three_neighbours = lil_matrix((self.background_mesh.n, self.background_mesh.n), dtype = np.int)
            BP_points = np.zeros((0), dtype = np.int)
            for j in range(0,self.background_mesh.n):
                patch3 = j
                for i in range(0,3):
                    patch_new = self.background_mesh.triangles_points_index[self.background_mesh.point_in_tri[patch3].nonzero()[1]].flatten()
                    patch3 = np.unique(np.append(patch3, patch_new))
                    new_patch3 = np.setdiff1d(patch3, self.background_mesh.three_neighbours[j].nonzero()[1])
                    self.background_mesh.three_neighbours[j, new_patch3] = i+1
                if self.is_point_BP[j,0] == 0:
                    xp = self.background_mesh.points[j]
                    other_ii = np.unique(self.background_mesh.triangles_points_index[self.background_mesh.point_in_tri[j].nonzero()[1]].flatten())
                    other_i = self.background_mesh.points[other_ii]
                    hp = np.max(la.norm(other_i - xp, axis = 1))
                    n_row = len(other_ii)
                    if n_row < 6:
                        for tri_i in self.background_mesh.point_in_tri[j].nonzero()[1]:
                            trii = self.background_mesh.triangles_points_index[tri_i]
                            edge_ii_not_j = np.setdiff1d(trii, j)
                            if not(all(self.is_point_BP[edge_ii_not_j,0] == 1)):
                                other_trii = self.background_mesh.triangles_points_index[np.setdiff1d(np.intersect1d(self.background_mesh.point_in_tri[edge_ii_not_j[0]].nonzero()[1], self.background_mesh.point_in_tri[edge_ii_not_j[1]].nonzero()[1]), tri_i)[0]]
                                other_ii = np.append(other_ii, np.setdiff1d(other_trii, edge_ii_not_j))
                    other_ii = np.unique(other_ii)
                    n_row = len(other_ii)
                    if n_row < 6:
                        print('n_row still < 6 patch_matrix background_mesh')

                    self.background_mesh.patch_matrix[j, other_ii] = other_ii+1
                    self.background_mesh.patch_matrix[j, j] = hp
                else:
                    BP_points = np.append(BP_points, j)

            self.background_mesh.BP_points_index = BP_points
            for j in BP_points:
                xp = self.background_mesh.points[j]
                other_ii = np.unique(self.background_mesh.triangles_points_index[self.background_mesh.point_in_tri[j].nonzero()[1]].flatten())
                other_i = self.background_mesh.points[other_ii]
                hp = np.max(la.norm(other_i - xp, axis = 1))
                n_row = len(other_ii)
                has_internal = any(self.is_point_BP[other_ii,1] == 0)
                new_other_ii = other_ii.copy()
                r = 2
                while not(has_internal):
                    for l in range(0,len(new_other_ii)):
                        for tri_i in self.background_mesh.point_in_tri[new_other_ii[l]].indices:
                            trii = self.background_mesh.triangles_points_index[tri_i]
                            for i in np.setdiff1d(trii, new_other_ii[l]):
                                if la.norm(self.background_mesh.points[i] - xp, 2) <= r * hp:
                                    other_ii = np.append(other_ii, i)
                    new_other_ii = np.unique(other_ii)
                    BP_points_bool = self.is_point_BP[new_other_ii,0] == 0
                    has_internal = any(BP_points_bool)
                    r = r+1

                where_internal = np.where(self.is_point_BP[other_ii,0] == 0)
                other_ii = np.union1d(other_ii, self.background_mesh.patch_matrix[other_ii[where_internal]].nonzero()[1])
                n_row = len(other_ii)
                if not(n_row - len(np.unique(other_ii)) == 0):
                    print('other_ii not made unique in grad phi calc', other_ii)
                self.background_mesh.patch_matrix[j, other_ii] = other_ii+1
                self.background_mesh.patch_matrix[j, j] = hp

        self.background_mesh.n_ga = np.zeros((self.background_mesh.n,2))
        self.background_mesh.n_t  = np.zeros((self.background_mesh.n,2))
        for j in range(0,self.background_mesh.n):
            xp = self.background_mesh.points[j]
            if update_count == 0:
                if self.two_particles == None and la.norm(np.array([ self.interface_gammaalpha0[0], self.interface_gammaalpha0[1]-self.b_ga]) - xp, 2) < 1e-11:
                    self.background_mesh.i_ghost_fixed = j
            other_ii = np.nonzero(self.background_mesh.patch_matrix[j])[1]
            other_i = self.background_mesh.points[other_ii]
            hp = self.background_mesh.patch_matrix[j, j]
            n_row = len(other_ii)

            eta = (other_i - xp)/hp
            M_eta = np.ones((n_row, 6))
            phi_ga_patch = np.zeros(n_row)
            phi_t_patch = np.zeros(n_row)
            for i in range(0,n_row):
                etaj = eta[i]
                M_eta[i,1:6] = np.array([etaj[0], etaj[1], etaj[0]**2, etaj[0] * etaj[1], etaj[1]**2])
                phi_ga_patch[i] = self.level_set_gammaalpha_enriched.phi_background[other_ii[i]]
                phi_t_patch[i] = self.level_set_alphatheta_enriched.phi_background[other_ii[i]]
            B_ga = la.lstsq(M_eta, phi_ga_patch)[0][[1,2]]
            B_t = la.lstsq(M_eta, phi_t_patch)[0][[1,2]]
            self.background_mesh.n_ga[j] = B_ga/la.norm(B_ga)
            self.background_mesh.n_t[j] = B_t/la.norm(B_t)



        if update_count == 0:
            self.background_mesh.edges_index = cGrid.unique_rows(np.sort(edges_i))
            self.background_mesh.edges = self.background_mesh.points[self.background_mesh.edges_index]
            self.background_mesh.n_edges = len(self.background_mesh.edges_index)

            edge_max = -1
            edge_min = 1e6
            # (#edges, 2) stores: [0] : 1 if boundary edge, 0 if not, [1] 1: bottom, 2:right, 3:upper, 4:left, 0:not boundary edge
            self.background_mesh.is_edge_BE = np.zeros((self.background_mesh.n_edges,2),dtype = int)
            self.background_mesh.edge_to_index = lil_matrix((self.N,self.N),dtype = int)
            for i in range(0,self.background_mesh.n_edges):
                edgeii = self.background_mesh.edges_index[i]
                edge = self.background_mesh.edges[i]
                if edge_max < la.norm(edge[0]-edge[1]):
                    edge_max = la.norm(edge[0]-edge[1])
                if edge_min > la.norm(edge[0]-edge[1]):
                    edge_min = la.norm(edge[0]-edge[1])
                if all(edge[:,0] == self.x0):
                    self.background_mesh.is_edge_BE[i,:] = np.array([1, 4])
                elif all(edge[:,0]  == self.xN):
                    self.background_mesh.is_edge_BE[i,:] = np.array([1, 2])
                elif all(edge[:,1] == self.y0):
                    self.background_mesh.is_edge_BE[i,:] = np.array([1, 1])
                elif all(edge[:,1]  == self.yN):
                    self.background_mesh.is_edge_BE[i,:] = np.array([1, 3])
                self.background_mesh.edge_to_index[edgeii[0],edgeii[1]] = i

            self.background_mesh.edge_in_tri = -np.ones((self.background_mesh.n_edges,2),dtype = int)
            self.background_mesh.tri_edges = -np.ones((self.background_mesh.n_tri,3),dtype = int)

            i=0
            for trii in self.background_mesh.triangles_points_index:
                tri = self.background_mesh.triangles[i]
                self.background_mesh.area_triangle[i] = cGrid.area(tri)
                k=0
                for edgei in np.array([[0,1],[0,2],[1,2]]):
                    edgeii =  np.sort(trii[edgei])
                    j = self.background_mesh.edge_to_index[edgeii[0],edgeii[1]]
                    self.background_mesh.tri_edges[i,k] = j
                    if self.background_mesh.edge_in_tri[j,0] == -1:
                        self.background_mesh.edge_in_tri[j,0] = i
                    else:
                        self.background_mesh.edge_in_tri[j,1] = i
                    k=k+1
                i=i+1

            self.background_mesh.h_mean = np.mean(la.norm(self.background_mesh.edges[:,0] - self.background_mesh.edges[:,1],2 , axis = 1))
            self.background_mesh.h_min = edge_min
            self.background_mesh.h_max = edge_max

        self.enriched_mesh.edges_index = self.background_mesh.edges_index.copy()
        self.enriched_mesh.n_edges = self.background_mesh.n_edges
        self.enriched_mesh.edge_to_index = self.background_mesh.edge_to_index.copy()

        #Points that will be shifted. 1st entry says if shifted (+1), 2nd to which interface, where
        #1 = gammaalpha, 2 = alphatheta, 3 = gammatheta, 4 is triple point
        self.will_point_be_shifted = -np.ones((self.enriched_mesh.n, 5))
        interface_ga_where_index = np.zeros(0, dtype = np.int)
        interface_at_where_index = np.zeros(0, dtype = np.int)
        i=0
        phi_ga = self.level_set_gammaalpha_enriched.phi_background
        phi_at = self.level_set_alphatheta_enriched.phi_background
        for trii in self.background_mesh.triangles_points_index:
            tri = self.background_mesh.points[trii]
            for edgei in np.array([[0,1],[0,2],[1,2]]):
                edgeii_sorted = np.sort(trii[edgei])
                edgeii = trii[edgei]
                j = self.background_mesh.edge_to_index[edgeii_sorted[0], edgeii_sorted[1]]
                edge = tri[edgei]
                ga_tri = phi_ga[edgeii[0]] * phi_ga[edgeii[1]] < 0
                at_tri = phi_at[edgeii[0]] * phi_at[edgeii[1]] < 0
                if at_tri:
                    taue_at = -phi_at[edgeii[0]]/(phi_at[edgeii[1]] - phi_at[edgeii[0]])
                    pe_at = (1-taue_at) * edge[0] + taue_at * edge[1]
                    e0_delta_at = taue_at > self.delta
                    e1_delta_at = taue_at < 1 - self.delta
                    if not(e0_delta_at):
                        if not(self.will_point_be_shifted[edgeii[0],1] == 4):
                            if self.will_point_be_shifted[edgeii[0],2] < 0:
                                self.will_point_be_shifted[edgeii[0]] = np.array([1,2, np.abs(phi_at[edgeii[0]]), pe_at[0], pe_at[1]])
                            elif self.will_point_be_shifted[edgeii[0],2] < la.norm(pe_at - edge[0]):
                                self.will_point_be_shifted[edgeii[0]] = np.array([1,2, np.abs(phi_at[edgeii[0]]), pe_at[0], pe_at[1]])
                    elif not(e1_delta_at):
                        if not(self.will_point_be_shifted[edgeii[1],1] == 4):
                            if self.will_point_be_shifted[edgeii[1],2] < 0:
                                self.will_point_be_shifted[edgeii[1]] = np.array([1,2, np.abs(phi_at[edgeii[1]]), pe_at[0], pe_at[1]])
                            elif self.will_point_be_shifted[edgeii[1],2] < la.norm(pe_at - edge[1]):
                                self.will_point_be_shifted[edgeii[1]] = np.array([1,2, np.abs(phi_at[edgeii[1]]), pe_at[0], pe_at[1]])
                if ga_tri:
                    taue_ga = -phi_ga[edgeii[0]]/(phi_ga[edgeii[1]] - phi_ga[edgeii[0]])
                    pe_ga = (1-taue_ga) * edge[0] + taue_ga * edge[1]
                    e0_delta_ga = taue_ga > self.delta
                    e1_delta_ga = taue_ga < 1 - self.delta
                    if not(e0_delta_ga):
                        if not(self.will_point_be_shifted[edgeii[0],1] == 4):
                            if self.will_point_be_shifted[edgeii[0],2] < 0:
                                self.will_point_be_shifted[edgeii[0]] = np.array([1,1, np.abs(phi_ga[edgeii[0]]), pe_ga[0], pe_ga[1]])
                            elif self.will_point_be_shifted[edgeii[0],2] < la.norm(pe_ga - edge[0]):
                                self.will_point_be_shifted[edgeii[0]] = np.array([1,1, np.abs(phi_ga[edgeii[0]]), pe_ga[0], pe_ga[1]])
                    elif not(e1_delta_ga):
                        if not(self.will_point_be_shifted[edgeii[1],1] == 4):
                            if self.will_point_be_shifted[edgeii[1],2] < 0:
                                self.will_point_be_shifted[edgeii[1]] = np.array([1,1, np.abs(phi_ga[edgeii[1]]), pe_ga[0], pe_ga[1]])
                            elif self.will_point_be_shifted[edgeii[1],2] < la.norm(pe_ga - edge[1]):
                                self.will_point_be_shifted[edgeii[1]] = np.array([1,1, np.abs(phi_ga[edgeii[1]]), pe_ga[0], pe_ga[1]])


            #If triangle has a point where phi < 0 and phi > 0, the interface has to be crossing this triangle
            ga_intersect = any(phi_ga[trii] > 0) and any(phi_ga[trii] < 0)
            at_intersect = any(phi_at[trii] > 0) and any(phi_at[trii] < 0)
            if ga_intersect:
                interface_ga_where_index = np.append(interface_ga_where_index, i)
            if at_intersect:
                interface_at_where_index = np.append(interface_at_where_index, i)


            #When both interface cut, it can be triple shift
            if at_intersect and ga_intersect:
                ga = 0
                at = 0
                for edgei in np.array([[0,1],[0,2],[1,2]]):
                    edgeii_sorted = np.sort(trii[edgei])
                    edgeii = trii[edgei]
                    j = self.background_mesh.edge_to_index[edgeii_sorted[0], edgeii_sorted[1]]
                    edge = tri[edgei]
                    ga_tri = phi_ga[edgeii[0]] * phi_ga[edgeii[1]] < 0
                    at_tri = phi_at[edgeii[0]] * phi_at[edgeii[1]] < 0
                    if at_tri:
                        taue_at = -phi_at[edgeii[0]]/(phi_at[edgeii[1]] - phi_at[edgeii[0]])
                        pe_at = (1-taue_at) * edge[0] + taue_at * edge[1]
                        if at == 0:
                            p01_at = pe_at
                        elif at == 1:
                            p02_at = pe_at
                        else:
                            print('3+ at cuts?')
                        at = at+1
                    if ga_tri:
                        taue_ga = -phi_ga[edgeii[0]]/(phi_ga[edgeii[1]] - phi_ga[edgeii[0]])
                        pe_ga = (1-taue_ga) * edge[0] + taue_ga * edge[1]
                        if ga == 0:
                            p01_ga = pe_ga
                        elif ga == 1:
                            p02_ga = pe_ga
                        else:
                            print('3+ ga cuts?')
                        ga = ga+1

                X = np.array( [[p02_ga[0] - p01_ga[0], p01_at[0] - p02_at[0]],
                               [p02_ga[1] - p01_ga[1], p01_at[1] - p02_at[1]]] )
                if la.det(X) != 0:
                    t = la.solve( X, np.array( [p01_at[0] - p01_ga[0], p01_at[1] - p01_ga[1]] ) )
                else:
                    t = np.ones(2) * np.inf
                if all(t >= 0) and all(t <= 1) and not(all(np.sort(t) == np.array([0,1]))) and not(all(t == np.zeros(2))) and not(all(t == np.ones(2))):
                    x_ga = (1-t[0]) * p01_ga + t[0] * p02_ga
                    x_at = (1-t[1]) * p01_at + t[1] * p02_at
                    if la.norm(x_ga - x_at) > 1e-14:
                        print('triple point not accurate, x_ga ', x_ga, 'x_at ', x_at)
                    lambda_barycentric = la.solve( np.array([ [tri[0,0], tri[1,0], tri[2,0]],
                                                                  [tri[0,1], tri[1,1], tri[2,1]],
                                                                  [1       , 1       , 1       ] ]), np.array([ x_ga[0], x_ga[1], 1]))

                    where_lambda_smaller_other_delta, = np.where(lambda_barycentric < self.delta) #diamond cut off delta
                    #triple shift
                    if where_lambda_smaller_other_delta.shape[0] == 2:
                        x_ga_i = trii[np.setdiff1d(np.arange(0,3),where_lambda_smaller_other_delta)][0]
                        self.will_point_be_shifted[x_ga_i] = np.array([1,4,0, x_ga[0], x_ga[1]])

            i = i+1

        interface_ga_where_index = np.unique(interface_ga_where_index)
        interface_at_where_index = np.unique(interface_at_where_index)

        where_triple_shift = np.zeros(0, dtype = np.int)
        i=0
        for trii in self.background_mesh.triangles_points_index:
            if all((self.will_point_be_shifted[trii,0]).astype(np.int) == 1):
                if (all((self.will_point_be_shifted[trii,1]).astype(np.int) == 1) or all((self.will_point_be_shifted[trii,1]).astype(np.int) == 2)):
                    where_triple_shift = np.append(where_triple_shift, i)
                elif any((self.will_point_be_shifted[trii,1]).astype(np.int) == 4) and not(any((self.will_point_be_shifted[trii,1]).astype(np.int) == 1) and (any((self.will_point_be_shifted[trii,1]).astype(np.int) == 2))):
                    where_triple_shift = np.append(where_triple_shift, i)
            tri = self.background_mesh.points[trii]
            self.background_mesh.area_triangle[i] = cGrid.area(tri)
            i=i+1


        self.trii_triple = np.zeros(0, dtype = np.int)

        #All triangles that have 3 points that will/can shift to the same interface will have one point changed to have already been shifted.
        #We pick the one which is furthest away from the interface, the distance is stored in the 3rd column
        not_shifted = np.zeros(0, dtype = np.int)
        for i in where_triple_shift:
            rot_tri = np.sign(self.background_mesh.area_triangle[i])
            trii = self.background_mesh.triangles_points_index[i]
            new_tri = self.will_point_be_shifted[trii, 3:5]
            rot_new_tri = np.sign(cGrid.area(new_tri))

            angles = np.zeros(3)
            a = new_tri[0] - new_tri[1]
            b = new_tri[0] - new_tri[2]
            angles[0] = np.arccos((a[0]*b[0] + a[1]*b[1])/(la.norm(a)*la.norm(b)))
            a = new_tri[1] - new_tri[0]
            b = new_tri[1] - new_tri[2]
            angles[1] = np.arccos((a[0]*b[0] + a[1]*b[1])/(la.norm(a)*la.norm(b)))
            angles[2] = np.pi - angles[0] - angles[1]
            skew_new_tri = max( (np.max(angles) - np.pi/3)/(np.pi - np.pi/3) , (np.pi/3 - np.min(angles))/(np.pi/3) )

#            ### With this code we don't shift furthest away point, if you want to use something else use something like this:
#            if rot_new_tri != rot_tri or skew_new_tri > .65:
#                print('new technique, should not be shifted', i)
#            else:
#                print('new technique, can be shifted', i)

            where_furthest = np.argmax(self.will_point_be_shifted[trii,2])
            self.has_point_been_shifted[trii[where_furthest],0] = 1
            not_shifted = np.append(not_shifted, trii[where_furthest])


        if self.background_mesh.i_ghost_fixed != -1:
            self.has_point_been_shifted[self.background_mesh.i_ghost_fixed] = np.hstack((1, 11))

        ### Find triple point locations
        if update_count <= 1:
            new_x3, shiftbendcut_tri_i = cGrid.find_triple(self, self.level_set_gammaalpha_enriched.phi_background, self.level_set_alphatheta_enriched.phi_background)
            print('new_x3 ')
            print(new_x3)
            print('which tri ', shiftbendcut_tri_i[:,0])
            
        ### Shift
        k_shift = -1
        old_has_been_shifted_background = np.zeros(self.background_mesh.n, dtype = np.int)
        while any(self.has_point_been_shifted[0:self.background_mesh.n, 0] != old_has_been_shifted_background):
            old_has_been_shifted_background = self.has_point_been_shifted[0:self.background_mesh.n, 0].copy()
            interface_ga_where_index_new_point = cGrid.shift(self, self.background_mesh.triangles_points_index, interface_ga_where_index, self.enriched_mesh.points.copy(), self.is_point_BP, self.level_set_gammaalpha_enriched.phi.copy(),1)
            interface_at_where_index_new_point = cGrid.shift(self, self.background_mesh.triangles_points_index, interface_at_where_index, self.enriched_mesh.points.copy(), self.is_point_BP, self.level_set_alphatheta_enriched.phi.copy(),2)
            k_shift = k_shift + 1
        print('shifted ', k_shift, 'times')
        self.multiple_shift = False

        ### Triple bend/shift/cut with triple points found before
            ### triple points done independent of cut/cut_twice for update_count <=1
        if update_count <= 1:
            for i in range(0, len(new_x3)):
                trii = self.background_mesh.triangles_points_index[shiftbendcut_tri_i[i,0]]
                patch_tri_i = np.unique(self.background_mesh.point_in_tri[trii].nonzero()[1].flatten())
                cGrid.triple_shift_bend_cut_fixed_triple(self, self.enriched_mesh.triangles_points_index, patch_tri_i, new_x3[i])
                ### Cutting done in triple bend/shift/cut 
        elif update_count == 2:
            self.trii_triple = np.zeros(0, dtype = np.int)
            interface_ga_where_index, interface_at_where_index = cGrid.triple_shift_bend_cut(self, self.enriched_mesh.triangles_points_index.copy())
        print('triple after  ', self.triple_points_index)

        self.is_point_BP = np.vstack((self.is_point_BP, np.zeros((self.enriched_mesh.n - self.background_mesh.n,2), dtype = np.int)))

        ### Shift
        k_shift = -1
        old_has_been_shifted_background = np.zeros(self.background_mesh.n, dtype = np.int)
        while any(self.has_point_been_shifted[0:self.background_mesh.n, 0] != old_has_been_shifted_background):
            old_has_been_shifted_background = self.has_point_been_shifted[0:self.background_mesh.n, 0].copy()
            interface_ga_where_index_new_point = cGrid.shift(self, self.enriched_mesh.triangles_points_index, interface_ga_where_index, self.enriched_mesh.points.copy(), self.is_point_BP, self.level_set_gammaalpha_enriched.phi.copy(),1)
            interface_at_where_index_new_point = cGrid.shift(self, self.enriched_mesh.triangles_points_index, interface_at_where_index, self.enriched_mesh.points.copy(), self.is_point_BP, self.level_set_alphatheta_enriched.phi.copy(),2)
            k_shift = k_shift + 1
        print('shifted ', k_shift, 'times')

        edges_i = np.zeros((0,2), dtype = int)

        ### Find triangles where to cut/cut_twice(both level-set functions change sign over this triangle)
        phi_ga = self.level_set_gammaalpha_enriched.phi
        phi_at = self.level_set_alphatheta_enriched.phi
        interface_ga_where_index = np.zeros(0, dtype = np.int)
        interface_at_where_index = np.zeros(0, dtype = np.int)
        for i in range(0,self.enriched_mesh.n_tri):
            trii = self.enriched_mesh.triangles_points_index[i]
            tri = self.enriched_mesh.points[trii]

            j = 0
            for edgei in np.array([[0,1],[0,2],[1,2]]):
                edgeii = np.sort(trii[edgei])
                edges_i = np.vstack((edges_i, edgeii))

                ga_intersect = (any(phi_ga[trii] > 0) and any(phi_ga[trii] < 0)) #or (any(phi_ga[trii] > 0) and any(phi_ga[trii] <= 0))
                at_intersect = (any(phi_at[trii] > 0) and any(phi_at[trii] < 0)) #or (any(phi_at[trii] > 0) and any(phi_at[trii] <= 0))
                if ga_intersect:
                    interface_ga_where_index = np.append(interface_ga_where_index, i)
                if at_intersect:
                    interface_at_where_index = np.append(interface_at_where_index, i)
                j=j+1
        self.enriched_mesh.edges_index = cGrid.unique_rows(np.sort(edges_i))
        self.enriched_mesh.edges = self.enriched_mesh.points[self.enriched_mesh.edges_index]
        self.enriched_mesh.n_edges = len(self.enriched_mesh.edges_index)

        self.enriched_mesh.edge_to_index = lil_matrix((self.enriched_mesh.n, self.enriched_mesh.n), dtype = np.int)
        self.enriched_mesh.edge_in_tri = -np.ones((self.enriched_mesh.n_edges,2),dtype = int)
        l = 0
        for edgeii in self.enriched_mesh.edges_index:
            self.enriched_mesh.edge_to_index[edgeii[0], edgeii[1]] = l
            l = l+1

        i = 0
        for trii in self.enriched_mesh.triangles_points_index:
            for edgei in np.array([[0,1],[0,2],[1,2]]):
                edgeii = np.sort(trii[edgei])
                l = self.enriched_mesh.edge_to_index[edgeii[0], edgeii[1]]
                if self.enriched_mesh.edge_in_tri[l,0] == -1:
                    self.enriched_mesh.edge_in_tri[l,0] = i
                else:
                    self.enriched_mesh.edge_in_tri[l,1] = i
            i = i+1

        interface_ga_at_where_index_new_point = np.intersect1d(interface_ga_where_index, interface_at_where_index)
        interface_ga_where_index_new_point = np.setdiff1d(interface_ga_where_index, interface_ga_at_where_index_new_point)
        interface_at_where_index_new_point = np.setdiff1d(interface_at_where_index, interface_ga_at_where_index_new_point)

        self.is_point_BP = np.vstack((self.is_point_BP, np.zeros((self.enriched_mesh.n - self.N,2), dtype = np.int)))

        #When an edge is cut the cut point is added, with has_edge_been_handled list we keep track if point is already added when handling another triangle
        #row j = which edge, column 0 is gamma/alpha points, 1 is alpha/theta
        self.has_edge_been_handled = -np.ones((self.enriched_mesh.n_edges, 2), dtype = np.int)
        
        ### Cut for triangles with only one level-set function changing sign
        cGrid.cut(self, self.enriched_mesh.triangles_points_index.copy(), interface_ga_where_index_new_point, self.is_point_BP, self.enriched_mesh.edge_to_index, self.level_set_gammaalpha_enriched.phi, 1)
        cGrid.cut(self, self.enriched_mesh.triangles_points_index.copy(), interface_at_where_index_new_point, self.is_point_BP, self.enriched_mesh.edge_to_index, self.level_set_alphatheta_enriched.phi, 2)

        ### Cut for triangles with bothlevel-set functions changing sign
        cGrid.cut_twice(self, self.enriched_mesh.triangles_points_index.copy(), interface_ga_at_where_index_new_point, self.is_point_BP, self.enriched_mesh.edge_to_index, self.level_set_gammaalpha_enriched.phi , self.level_set_alphatheta_enriched.phi, 1, 2)


        ### Find domains, get useful information (indices, parametrisation of ghost interface, etc.)
        self.enriched_mesh.triangles = self.enriched_mesh.points[self.enriched_mesh.triangles_points_index]
        self.is_point_BP = np.vstack((self.is_point_BP, np.zeros((self.enriched_mesh.n - len(self.is_point_BP),2),dtype = np.int)))
        for i in range(self.N, self.enriched_mesh.n):
            p = self.enriched_mesh.points[i]
            # (#edges, 2) stores: [0] : 1 if boundary edge, 0 if not, [1] 1: bottom, 2:right, 3:upper, 4:left, 0:not boundary point
            if p[0] == self.x0:
                self.is_point_BP[i] = [1,4]
            if p[0] == self.xN:
                self.is_point_BP[i] = [1,2]
            if p[1] == self.y0:
                self.is_point_BP[i] = [1,1]
            if p[1] == self.yN:
                self.is_point_BP[i] = [1,3]
            #cornerpoint 5
            if p[0] == self.x0 and p[1] == self.y0 or p[0] == self.xN and p[1]== self.y0 or p[0] == self.x0 and p[1] == self.yN or p[0] == self.xN and p[1] == self.yN:
                self.is_point_BP[i,1] = 5



        self.enriched_mesh.point_in_tri = lil_matrix((self.enriched_mesh.n, self.enriched_mesh.n_tri), dtype = np.int)
        self.enriched_mesh.area_triangle = -np.ones(self.enriched_mesh.n_tri)
        for i in range(0,self.enriched_mesh.n_tri):
            trii = self.enriched_mesh.triangles_points_index[i]
            self.enriched_mesh.point_in_tri[trii,i] = i+1
            self.enriched_mesh.area_triangle[i] = cGrid.area(tri)

        #Set not shifted points cause of trii with all corners shifting back to -1. In case triple point is said to not be shifted, ignore
        self.has_point_been_shifted[np.setdiff1d(not_shifted, self.triple_points_index)] = -1


        edge_max = 0
        edge_min = max(self.xN - self.x0, self.yN - self.y0)
        edge_ii_ga_to_be_deleted = np.zeros((0,2), dtype = np.int)
        edge_ii_ga_ghost_to_be_deleted = np.zeros((0,2), dtype = np.int)
        edge_ii_gt_to_be_deleted = np.zeros((0,2), dtype = np.int)
        edge_ii_at_to_be_deleted = np.zeros((0,2), dtype = np.int)
        self.background_mesh.i_ghost_fixed_shifted = False
        ### Pass each enriched triangle to see in what domain it is, when a phi = 0 on whole triangle, find out where it belongs
        for i in range(0,self.enriched_mesh.n_tri):
            trii = self.enriched_mesh.triangles_points_index[i]
            tri = self.enriched_mesh.points[trii]
            
            self.enriched_mesh.area_triangle[i] = cGrid.area(tri)

            if self.two_particles == None:
                lambda_barycentric = la.solve( np.array([ [tri[0,0], tri[1,0], tri[2,0]],
                                                          [tri[0,1], tri[1,1], tri[2,1]],
                                                          [1       , 1       , 1       ] ]), np.array([ self.interface_gammaalpha0[0], self.interface_gammaalpha0[1]-self.b_ga, 1]))
                if all(lambda_barycentric >= 0) and all(lambda_barycentric <= 1):
                    triple_Tau = np.zeros(self.enriched_mesh.n)
                    triple_Tau[trii] = lambda_barycentric
                    self.enriched_mesh.Tau_fixed_ghost_point = triple_Tau


            if all(self.level_set_alphatheta_enriched.phi[trii] >= 0):
                self.precipitate_mesh_theta.triangles_points_index = np.vstack((self.precipitate_mesh_theta.triangles_points_index, trii))
                self.precipitate_mesh_theta.triangles_index = np.hstack((self.precipitate_mesh_theta.triangles_index, i))
            elif all(self.level_set_gammaalpha_enriched.phi[trii] <= 0) and all(self.level_set_alphatheta_enriched.phi[trii] <= 0):
                self.diffusion_mesh_gamma.triangles_points_index = np.vstack((self.diffusion_mesh_gamma.triangles_points_index, trii))
                self.diffusion_mesh_gamma.triangles_index = np.hstack((self.diffusion_mesh_gamma.triangles_index, i))
            elif all(self.level_set_gammaalpha_enriched.phi[trii] >= 0) and all(self.level_set_alphatheta_enriched.phi[trii] <= 0):
                self.diffusion_mesh_alpha.triangles_points_index = np.vstack((self.diffusion_mesh_alpha.triangles_points_index, trii))
                self.diffusion_mesh_alpha.triangles_index = np.hstack((self.diffusion_mesh_alpha.triangles_index, i))


            triple_shift = False
            ga_count = np.count_nonzero(self.has_point_been_shifted[trii, 1] == 1)
            ga_ghost_count = np.count_nonzero(self.has_point_been_shifted[trii, 1] == 11)
            gt_count = np.count_nonzero(self.has_point_been_shifted[trii, 1] == 3)
            at_count = np.count_nonzero(self.has_point_been_shifted[trii, 1] == 2)
            triple_count = np.count_nonzero(self.has_point_been_shifted[trii, 1]%4 == 0)
            if ga_count+triple_count == 3 or gt_count+triple_count == 3 or at_count+triple_count == 3 or ga_ghost_count+triple_count == 3:
                triple_shift = True

                print('triangle with phi = 0, i =', i)
                print('trii ', trii)
                interface_type = -1
                if ga_count >= 2:
                    interface_type = 1
                elif ga_ghost_count >= 2:
                    interface_type = 11
                elif gt_count >= 2:
                    interface_type = 3
                elif at_count >= 2:
                    interface_type = 2
                elif triple_count == 2:
                    interface_type = 4
                    #find out which interface is dissolved (gamma theta or alpha theta)
                    patch_triples = np.unique(self.enriched_mesh.triangles_points_index[self.enriched_mesh.point_in_tri[np.intersect1d(trii, self.triple_points_index)].nonzero()[1]])
                    gt_count_patch_triples = np.count_nonzero(self.has_point_been_shifted[patch_triples, 1] == 3)
                    at_count_patch_triples = np.count_nonzero(self.has_point_been_shifted[patch_triples, 1] == 2)

                print('which interface? ',interface_type)

                single_point = np.zeros(0, dtype = np.int)
                other_ii = np.zeros(0, dtype = np.int)
                if interface_type == 11:
                    for ii in trii:
                        if not(any(self.triple_points_index == ii)):
                            patch_ii = np.setdiff1d(np.unique(self.enriched_mesh.triangles_points_index[self.enriched_mesh.point_in_tri[ii].nonzero()[1]].flatten()), trii)
                            if all(self.has_point_been_shifted[patch_ii,1] != interface_type) and all(self.has_point_been_shifted[patch_ii,1]%4 != 0):
                                single_point = ii
                                other_ii = np.setdiff1d(trii, single_point)
                elif interface_type == 1:
                    for ii in trii:
                            patch_ii = np.setdiff1d(np.unique(self.enriched_mesh.triangles_points_index[self.enriched_mesh.point_in_tri[ii].nonzero()[1]].flatten()), trii)
                            if all(self.has_point_been_shifted[patch_ii,1]%10 != interface_type) and all(self.has_point_been_shifted[patch_ii,1]%4 != 0):
                                single_point = ii
                                other_ii = np.setdiff1d(trii, single_point)
                elif interface_type == 2 or interface_type == 3:
                    for ii in trii:
                            patch_ii = np.setdiff1d(np.unique(self.enriched_mesh.triangles_points_index[self.enriched_mesh.point_in_tri[ii].nonzero()[1]].flatten()), trii)
                            if all(self.has_point_been_shifted[patch_ii,1] != interface_type) and all(self.has_point_been_shifted[patch_ii,1]%4 != 0):
                                single_point = ii
                                other_ii = np.setdiff1d(trii, single_point)
                if len(other_ii) != 0:
                    if interface_type == 1:
                        self.interface_gammaalpha.edges_index = np.vstack((self.interface_gammaalpha.edges_index, np.sort(np.hstack((other_ii[0], single_point))), np.sort(np.hstack((other_ii[1], single_point))) ))
                        edge_ii_ga_to_be_deleted = np.vstack((edge_ii_ga_to_be_deleted, other_ii))
                    elif interface_type == 11:
                        self.interface_gammaalpha.ghost_edges_index = np.vstack((self.interface_gammaalpha.ghost_edges_index, np.sort(np.hstack((other_ii[0], single_point))), np.sort(np.hstack((other_ii[1], single_point))) ))
                        edge_ii_ga_ghost_to_be_deleted = np.vstack((edge_ii_ga_ghost_to_be_deleted, other_ii))
                    elif interface_type == 3:
                        self.interface_gammatheta.edges_index = np.vstack((self.interface_gammatheta.edges_index, np.sort(np.hstack((other_ii[0], single_point))), np.sort(np.hstack((other_ii[1], single_point))) ))
                        edge_ii_gt_to_be_deleted = np.vstack((edge_ii_gt_to_be_deleted, other_ii))
                    elif interface_type == 2:
                        self.interface_alphatheta.edges_index = np.vstack((self.interface_alphatheta.edges_index, np.sort(np.hstack((other_ii[0], single_point))), np.sort(np.hstack((other_ii[1], single_point))) ))
                        edge_ii_at_to_be_deleted = np.vstack((edge_ii_at_to_be_deleted, other_ii))
                if interface_type == 4:
                    if at_count_patch_triples == 2 and gt_count_patch_triples == 0:
                        self.interface_gammatheta.edges_index = np.vstack((self.interface_gammatheta.edges_index, np.sort(np.intersect1d(self.triple_points_index,trii)) ))
                    elif gt_count_patch_triples == 2 and at_count_patch_triples == 0:
                        self.interface_alphatheta.edges_index = np.vstack((self.interface_alphatheta.edges_index, np.sort(np.intersect1d(self.triple_points_index,trii)) ))

                    if ga_ghost_count == 1:
                        edge_ii_ga_ghost_to_be_deleted = np.vstack((edge_ii_ga_ghost_to_be_deleted, np.sort(np.intersect1d(self.triple_points_index,trii))))
                    elif ga_count == 1:
                        triples_trii = np.intersect1d(self.triple_points_index, trii)
                        triple_path = -1
                        for x_i in range(0,2):
                            patch_x3_i = np.setdiff1d(np.unique(self.enriched_mesh.triangles_points_index[self.enriched_mesh.point_in_tri[triples_trii[x_i]].nonzero()[1]].flatten()), trii)
                            where_ga_patch_x3_i, = np.where(self.has_point_been_shifted[patch_x3_i,1] == 1)
                            for x_ga in patch_x3_i[where_ga_patch_x3_i]:
                                patch_ga = np.setdiff1d(np.unique(self.enriched_mesh.triangles_points_index[self.enriched_mesh.point_in_tri[x_ga].nonzero()[1]].flatten()), triples_trii)
                                where_ga_patch_ga_i, = np.where(self.has_point_been_shifted[patch_ga,1] == 1)
                                if len(where_ga_patch_ga_i) == 2:
                                    if triple_path != -1:
                                        print('found multiple points around triple x_i', triples_trii[x_i], x_i, 'which say this is triple ga should go through')
                                    triple_path = x_i
                        if triple_path != -1:
                            edge_ii_ga_to_be_deleted = np.vstack((edge_ii_ga_to_be_deleted, np.sort(np.hstack((np.setdiff1d(trii, triples_trii), triples_trii[triple_path]))) ))
                        else:
                            print('not found triple path point')
            elif triple_count == 2:
                #find out which interface is dissolved (gamma theta or alpha theta)
                patch_triples = np.unique(self.enriched_mesh.triangles_points_index[self.enriched_mesh.point_in_tri[np.intersect1d(trii, self.triple_points_index)].nonzero()[1]])
                gt_count_patch_triples = np.count_nonzero(self.has_point_been_shifted[patch_triples, 1] == 3)
                at_count_patch_triples = np.count_nonzero(self.has_point_been_shifted[patch_triples, 1] == 2)
                if at_count_patch_triples == 2 and gt_count_patch_triples == 0:
                    self.interface_gammatheta.edges_index = np.vstack((self.interface_gammatheta.edges_index, np.sort(np.intersect1d(self.triple_points_index,trii)) ))
                elif gt_count_patch_triples == 2 and at_count_patch_triples == 0:
                    self.interface_alphatheta.edges_index = np.vstack((self.interface_alphatheta.edges_index, np.sort(np.intersect1d(self.triple_points_index,trii)) ))

                print('triangle with two triple points and no other interface point')
                print('at/dt_count_patches ', at_count_patch_triples, gt_count_patch_triples)


            ga_at = 0
            ga = 0
            at = 0
            for edgei in np.array([[0,1],[0,2],[1,2]]):
                edgeii = trii[edgei]
                edge = tri[edgei]
                if edge_max < la.norm(edge[0]-edge[1]):
                    edge_max = la.norm(edge[0]-edge[1])
                if edge_min > la.norm(edge[0]-edge[1]):
                    edge_min = la.norm(edge[0]-edge[1])

                ### If not phi = 0 on this triangle, add edges
                if not(triple_shift):
                    point_in_tri0 = self.enriched_mesh.point_in_tri[edgeii[0]].nonzero()[1]
                    point_in_tri1 = self.enriched_mesh.point_in_tri[edgeii[1]].nonzero()[1]
                    other_tri_i = np.setdiff1d(np.intersect1d(point_in_tri0, point_in_tri1), i)
                    other_trii = self.enriched_mesh.triangles_points_index[other_tri_i]
                    ### Determine to which interface edge belongs
                    if all(self.has_point_been_shifted[edgeii, 1] == 1) or (any(self.has_point_been_shifted[edgeii, 1] == 1) and any(self.has_point_been_shifted[edgeii, 1]%4 == 0)):
                        try:
                            sign_tri = np.sign(self.level_set_gammaalpha_enriched.phi[np.setdiff1d(trii, edgeii)[0]])
                            sign_other_tri = np.sign(self.level_set_gammaalpha_enriched.phi[np.setdiff1d(other_trii, edgeii)[0]])
                            sign_tri = np.sign(self.level_set_gammaalpha_enriched.phi[np.setdiff1d(trii, edgeii)[0]])
                            sign_other_tri = np.sign(self.level_set_gammaalpha_enriched.phi[np.setdiff1d(other_trii, edgeii)[0]])
                            if sign_other_tri != sign_tri:
                                self.interface_gammaalpha.edges_index = np.vstack((self.interface_gammaalpha.edges_index, np.sort(edgeii)))
                            else:
                                patch0 = np.setdiff1d(np.unique(self.enriched_mesh.triangles_points_index[point_in_tri0].flatten()), edgeii)
                                patch1 = np.setdiff1d(np.unique(self.enriched_mesh.triangles_points_index[point_in_tri1].flatten()), edgeii)
                                if  np.abs(np.sum(np.sign(self.level_set_gammaalpha_enriched.phi[patch0]))) >= len(patch0) - 1:
                                    self.level_set_gammaalpha_enriched.phi[edgeii[0]] = sign_tri * la.norm(self.enriched_mesh.points[edgeii[0]] - self.enriched_mesh.points[edgeii[1]], 2)
                                    if edgeii[0] < self.N:
                                        self.level_set_gammaalpha_enriched.phi_background[edgeii[0]] = self.level_set_gammaalpha_enriched.phi[edgeii[0]]
                                if  np.abs(np.sum(np.sign(self.level_set_gammaalpha_enriched.phi[patch1]))) >= len(patch1) - 1:
                                    self.level_set_gammaalpha_enriched.phi[edgeii[1]] = sign_tri * la.norm(self.enriched_mesh.points[edgeii[0]] - self.enriched_mesh.points[edgeii[1]], 2)
                                    if edgeii[1] < self.N:
                                        self.level_set_gammaalpha_enriched.phi_background[edgeii[1]] = self.level_set_gammaalpha_enriched.phi[edgeii[1]]
                        except:
                            pass
#                            print('Probably boundary edge')
#                            self.interface_gammaalpha.edges_index = np.vstack((self.interface_gammaalpha.edges_index, np.sort(edgeii)))


                    elif all(self.has_point_been_shifted[edgeii, 1] == 11) or (any(self.has_point_been_shifted[edgeii, 1] == 11) and any(self.has_point_been_shifted[edgeii, 1]%4 == 0)):
                        sign_tri = np.sign(self.level_set_gammaalpha_enriched.phi[np.setdiff1d(trii, edgeii)[0]])
                        sign_other_tri = np.sign(self.level_set_gammaalpha_enriched.phi[np.setdiff1d(other_trii, edgeii)[0]])
                        if sign_other_tri != sign_tri:
                            self.interface_gammaalpha.ghost_edges_index = np.vstack((self.interface_gammaalpha.ghost_edges_index, np.sort(edgeii)))
                        else:
                            patch0 = np.setdiff1d(np.unique(self.enriched_mesh.triangles_points_index[point_in_tri0].flatten()), edgeii)
                            patch1 = np.setdiff1d(np.unique(self.enriched_mesh.triangles_points_index[point_in_tri1].flatten()), edgeii)
                            if np.abs(np.sum(np.sign(self.level_set_gammaalpha_enriched.phi[patch0]))) >= len(patch0) - 1:
                                self.level_set_gammaalpha_enriched.phi[edgeii[0]] = sign_tri * la.norm(self.enriched_mesh.points[edgeii[0]] - self.enriched_mesh.points[edgeii[1]], 2)
                                if edgeii[0] < self.N:
                                    self.level_set_gammaalpha_enriched.phi_background[edgeii[0]] = self.level_set_gammaalpha_enriched.phi[edgeii[0]]
                            if  np.abs(np.sum(np.sign(self.level_set_gammaalpha_enriched.phi[patch1]))) >= len(patch1) - 1:
                                self.level_set_gammaalpha_enriched.phi[edgeii[1]] = sign_tri * la.norm(self.enriched_mesh.points[edgeii[0]] - self.enriched_mesh.points[edgeii[1]], 2)
                                if edgeii[1] < self.N:
                                    self.level_set_gammaalpha_enriched.phi_background[edgeii[1]] = self.level_set_gammaalpha_enriched.phi[edgeii[1]]
                            if any(edgeii == self.background_mesh.i_ghost_fixed) and not(self.background_mesh.i_ghost_fixed_shifted):
                                print('tri_i ', i, 'trii ', trii)
                                if edgeii[0] == self.background_mesh.i_ghost_fixed:
                                    patch_copy = patch1
                                    searched = np.array([edgeii[1]])
                                else:
                                    patch_copy = patch0
                                    searched = np.array([edgeii[0]])
                                where_ga_ghost, = np.where(self.has_point_been_shifted[patch_copy, 1] == 11)
                                r = 0
                                while len(where_ga_ghost) <= 1:
                                    searched = np.append(searched, patch_copy[where_ga_ghost])
                                    patch_copy = np.setdiff1d(np.unique(self.enriched_mesh.triangles_points_index[self.background_mesh.point_in_tri[patch_copy[where_ga_ghost]].nonzero()[1]].flatten()), searched)
                                    where_ga_ghost, = np.where(self.has_point_been_shifted[patch_copy, 1] == 11)
                                    r = r+1
                                    if r > 20:
                                        print('couldnt find new fixed point')
                                        break
                                other_ii_ghost = patch_copy[where_ga_ghost]
                                print('searched ', searched)
                                print('other_ii_ghost ', other_ii_ghost)
                                if searched[len(searched)-1] < self.N:
                                    self.background_mesh.i_ghost_fixed = searched[len(searched)-1]
                                    self.background_mesh.points[searched[len(searched)-1]] = self.enriched_mesh.points[searched[len(searched)-1]]
                                else:
                                    if all(other_ii_ghost < self.N):
                                        shift_point = other_ii_ghost[np.argmin(la.norm(self.enriched_mesh.points[searched[len(searched)-1]] - self.enriched_mesh.points[other_ii_ghost], 2, axis = 1))]
                                    elif any(other_ii_ghost < self.N):
                                        shift_point = other_ii_ghost[np.where(other_ii_ghost < self.N)[0]]
                                    else:
                                        print('when looking for new i_ghost_fixed the connecting point was a cut point And both its neighbouring ghost points. cause I was too lazy to implement further as this probably not happens this has now gone wrong. should be easy fixable by making a while loop: while not(any(other_ii_ghost < self.N) ):')
                                    self.background_mesh.i_ghost_fixed = shift_point
                                    self.background_mesh.points[other_ii_ghost] = self.enriched_mesh.points[shift_point]
                                self.background_mesh.i_ghost_fixed_shifted = True

                    elif all(self.has_point_been_shifted[edgeii, 1] == 3) or (any(self.has_point_been_shifted[edgeii, 1] == 3) and any(self.has_point_been_shifted[edgeii, 1]%4 == 0)):
                        sign_tri = np.sign(self.level_set_alphatheta_enriched.phi[np.setdiff1d(trii, edgeii)[0]])
                        sign_other_tri = np.sign(self.level_set_alphatheta_enriched.phi[np.setdiff1d(other_trii, edgeii)[0]])
                        if sign_other_tri != sign_tri:
                            self.interface_gammatheta.edges_index = np.vstack((self.interface_gammatheta.edges_index, np.sort(edgeii)))
                        else:
                            patch0 = np.setdiff1d(np.unique(self.enriched_mesh.triangles_points_index[point_in_tri0].flatten()), edgeii)
                            patch1 = np.setdiff1d(np.unique(self.enriched_mesh.triangles_points_index[point_in_tri1].flatten()), edgeii)
                            if  np.abs(np.sum(np.sign(self.level_set_alphatheta_enriched.phi[patch0]))) >= len(patch0) - 1:
                                self.level_set_alphatheta_enriched.phi[edgeii[0]] = sign_tri * la.norm(self.enriched_mesh.points[edgeii[0]] - self.enriched_mesh.points[edgeii[1]], 2)
                                if edgeii[0] < self.N:
                                    self.level_set_alphatheta_enriched.phi_background[edgeii[0]] = self.level_set_alphatheta_enriched.phi[edgeii[0]]
                            if np.abs(np.sum(np.sign(self.level_set_alphatheta_enriched.phi[patch1]))) >= len(patch1) - 1:
                                self.level_set_alphatheta_enriched.phi[edgeii[1]] = sign_tri * la.norm(self.enriched_mesh.points[edgeii[0]] - self.enriched_mesh.points[edgeii[1]], 2)
                                if edgeii[1] < self.N:
                                    self.level_set_alphatheta_enriched.phi_background[edgeii[1]] = self.level_set_alphatheta_enriched.phi[edgeii[1]]
                    elif all(self.has_point_been_shifted[edgeii, 1] == 2) or (any(self.has_point_been_shifted[edgeii, 1] == 2) and any(self.has_point_been_shifted[edgeii, 1]%4 == 0)):
                        sign_tri = np.sign(self.level_set_alphatheta_enriched.phi[np.setdiff1d(trii, edgeii)[0]])
                        sign_other_tri = np.sign(self.level_set_alphatheta_enriched.phi[np.setdiff1d(other_trii, edgeii)[0]])
                        if sign_other_tri != sign_tri:
                            self.interface_alphatheta.edges_index = np.vstack((self.interface_alphatheta.edges_index, np.sort(edgeii)))
                        else:
                            patch0 = np.setdiff1d(np.unique(self.enriched_mesh.triangles_points_index[point_in_tri0].flatten()), edgeii)
                            patch1 = np.setdiff1d(np.unique(self.enriched_mesh.triangles_points_index[point_in_tri1].flatten()), edgeii)
                            if np.abs(np.sum(np.sign(self.level_set_alphatheta_enriched.phi[patch0]))) >= len(patch0) - 1:
                                self.level_set_alphatheta_enriched.phi[edgeii[0]] = sign_tri * la.norm(self.enriched_mesh.points[edgeii[0]] - self.enriched_mesh.points[edgeii[1]], 2)
                                if edgeii[0] < self.N:
                                    self.level_set_alphatheta_enriched.phi_background[edgeii[0]] = self.level_set_alphatheta_enriched.phi[edgeii[0]]
                            if np.abs(np.sum(np.sign(self.level_set_alphatheta_enriched.phi[patch1]))) >= len(patch1) - 1:
                                self.level_set_alphatheta_enriched.phi[edgeii[1]] = sign_tri * la.norm(self.enriched_mesh.points[edgeii[0]] - self.enriched_mesh.points[edgeii[1]], 2)
                                if edgeii[1] < self.N:
                                    self.level_set_alphatheta_enriched.phi_background[edgeii[1]] = self.level_set_alphatheta_enriched.phi[edgeii[1]]

        ### Sometimes triple points collapse and one triple point is still left. We delete this triple point
        self.triple_points_index = np.sort(self.triple_points_index)
        if len(self.triple_points_index)%2 == 1:
            i = 0
            triple_disappear = False
            for x3 in self.triple_points_index:
                patch_triple = np.unique(self.enriched_mesh.triangles_points_index[self.enriched_mesh.point_in_tri[x3].nonzero()[1]])
                gt_count_patch_triples = np.count_nonzero(self.has_point_been_shifted[patch_triple, 1] == 3)
                at_count_patch_triples = np.count_nonzero(self.has_point_been_shifted[patch_triple, 1] == 2)
                ### Find out which interface disappeared 
                if at_count_patch_triples >= 2 and gt_count_patch_triples == 0:
                    self.has_point_been_shifted[x3, 1] = 2
                    triple_disappear = True
                elif at_count_patch_triples == 0 and gt_count_patch_triples >= 2:
                    self.has_point_been_shifted[x3, 1] = 3
                    triple_disappear = True
                else:
                    if self.two_particles == None:
                        print('triple point vanishing has both/no/not enough (?) gt/at neighbours, gt/at-count: ', gt_count_patch_triples, at_count_patch_triples)


                if triple_disappear:
                    ### If disappeared in one particle model, ghost fixed point has to be gone
                    if self.two_particles == None:
                        self.has_point_been_shifted[self.background_mesh.i_ghost_fixed] = np.array([-1, -1])
                        
                    ### Reinit this triple point value to min distance interface points. Assumed here that it is gamma/theta-interface that disappeared
                    where_ga_neighbour = patch_triple[np.where(self.has_point_been_shifted[patch_triple, 1] == 1)[0]]
                    if type(where_ga_neighbour) == int:
                        self.level_set_gammaalpha_enriched.phi[x3] = la.norm(self.enriched_mesh.points[x3] - self.enriched_mesh.points[where_ga_neighbour], 2)
                    else:
                        distances = la.norm(self.enriched_mesh.points[x3] - self.enriched_mesh.points[where_ga_neighbour], 2, axis = 1)
                        self.level_set_gammaalpha_enriched.phi[x3] = distances[np.argmin(distances)]

                    if self.two_particles == None:
                        self.level_set_gammaalpha_enriched.phi[self.background_mesh.i_ghost_fixed] = la.norm(self.enriched_mesh.points[self.background_mesh.i_ghost_fixed] - self.enriched_mesh.points[x3], 2) + self.level_set_gammaalpha_enriched.phi[x3]
                        self.level_set_gammaalpha_enriched.phi_background[self.background_mesh.i_ghost_fixed] = self.level_set_gammaalpha_enriched.phi[self.background_mesh.i_ghost_fixed]

                    if x3 < self.N:
                        self.level_set_gammaalpha_enriched.phi_background[x3] = self.level_set_gammaalpha_enriched.phi[x3]
                    if self.two_particles == None:
                        self.background_mesh.i_ghost_fixed = -1

                    self.triple_points_index = np.delete(self.triple_points_index, i, 0)

                i = i+1

        self.enriched_mesh.h_max = edge_max
        self.enriched_mesh.h_min = edge_min
        self.enriched_mesh.h_mean = np.mean(la.norm(self.enriched_mesh.edges[:,0] - self.enriched_mesh.edges[:,1],2 , axis = 1))


        self.interface_gammaalpha.edges_index = cGrid.unique_rows(self.interface_gammaalpha.edges_index)
        self.interface_gammaalpha.ghost_edges_index = cGrid.unique_rows(self.interface_gammaalpha.ghost_edges_index)
        self.interface_alphatheta.edges_index = cGrid.unique_rows(self.interface_alphatheta.edges_index)
        self.interface_gammatheta.edges_index = cGrid.unique_rows(self.interface_gammatheta.edges_index)

        for i in range(0, edge_ii_ga_to_be_deleted.shape[0]):
            where_edge_ii = np.intersect1d(np.where(self.interface_gammaalpha.edges_index[:,0] == edge_ii_ga_to_be_deleted[i,0]), np.where(self.interface_gammaalpha.edges_index[:,1] == edge_ii_ga_to_be_deleted[i,1]))
            self.interface_gammaalpha.edges_index = np.delete(self.interface_gammaalpha.edges_index, where_edge_ii, axis = 0)
        for i in range(0, edge_ii_ga_ghost_to_be_deleted.shape[0]):
            where_edge_ii = np.intersect1d(np.where(self.interface_gammaalpha.ghost_edges_index[:,0] == edge_ii_ga_ghost_to_be_deleted[i,0]), np.where(self.interface_gammaalpha.ghost_edges_index[:,1] == edge_ii_ga_ghost_to_be_deleted[i,1]))
            self.interface_gammaalpha.ghost_edges_index = np.delete(self.interface_gammaalpha.ghost_edges_index, where_edge_ii, axis = 0)
        for i in range(0, edge_ii_gt_to_be_deleted.shape[0]):
            where_edge_ii = np.intersect1d(np.where(self.interface_gammatheta.edges_index[:,0] == edge_ii_gt_to_be_deleted[i,0]), np.where(self.interface_gammatheta.edges_index[:,1] == edge_ii_gt_to_be_deleted[i,1]))
            self.interface_gammatheta.edges_index = np.delete(self.interface_gammatheta.edges_index, where_edge_ii, axis = 0)
        for i in range(0, edge_ii_at_to_be_deleted.shape[0]):
            where_edge_ii = np.intersect1d(np.where(self.interface_alphatheta.edges_index[:,0] == edge_ii_at_to_be_deleted[i,0]), np.where(self.interface_alphatheta.edges_index[:,1] == edge_ii_at_to_be_deleted[i,1]))
            self.interface_alphatheta.edges_index = np.delete(self.interface_alphatheta.edges_index, where_edge_ii, axis = 0)

        self.interface_gammaalpha.edges = self.enriched_mesh.points[self.interface_gammaalpha.edges_index]
        self.interface_alphatheta.edges = self.enriched_mesh.points[self.interface_alphatheta.edges_index]
        self.interface_gammatheta.edges = self.enriched_mesh.points[self.interface_gammatheta.edges_index]

        self.interface_gammaalpha.n_edges = len(self.interface_gammaalpha.edges_index)
        self.interface_gammatheta.n_edges = len(self.interface_gammatheta.edges_index)
        self.interface_alphatheta.n_edges = len(self.interface_alphatheta.edges_index)

        self.enriched_mesh.triangles = self.enriched_mesh.points[self.enriched_mesh.triangles_points_index]

        self.interface_gammaalpha.points_index = np.unique(self.interface_gammaalpha.edges_index.flatten())
        self.interface_gammaalpha.ghost_points_index = np.unique(self.interface_gammaalpha.ghost_edges_index.flatten())

        self.has_point_been_shifted[np.setdiff1d(self.interface_gammaalpha.ghost_points_index, self.triple_points_index), 1] = np.int(11)

        self.interface_gammatheta.points_index = np.unique(self.interface_gammatheta.edges_index.flatten())
        self.interface_alphatheta.points_index = np.unique(self.interface_alphatheta.edges_index.flatten())

        self.interface_gammaalpha.points = self.enriched_mesh.points[self.interface_gammaalpha.points_index]
        self.interface_gammaalpha.ghost_points = self.enriched_mesh.points[self.interface_gammaalpha.ghost_points_index]
        self.interface_gammaalpha.ghost_n = len(self.interface_gammaalpha.ghost_points_index)
        self.interface_gammatheta.points = self.enriched_mesh.points[self.interface_gammatheta.points_index]
        self.interface_alphatheta.points = self.enriched_mesh.points[self.interface_alphatheta.points_index]

        self.interface_gammaalpha.triple_points_index = -np.ones(len(self.triple_points_index), dtype = np.int)
        self.interface_gammaalpha.ghost_triple_points_index = -np.ones(len(self.triple_points_index), dtype = np.int)
        self.interface_gammatheta.triple_points_index = -np.ones(len(self.triple_points_index), dtype = np.int)
        self.interface_alphatheta.triple_points_index = -np.ones(len(self.triple_points_index), dtype = np.int)
        i = 0
        for x_i in self.triple_points_index:
#            print(self.triple_points_index, '\n', np.where(self.interface_gammatheta.points_index == x_i)[0], np.where(self.interface_gammaalpha.points_index == x_i)[0])
#            print(self.interface_gammaalpha.triple_points_index, self.interface_gammatheta.triple_points_index)
            self.interface_gammaalpha.triple_points_index[i] = np.where(self.interface_gammaalpha.points_index == x_i)[0]
            self.interface_gammatheta.triple_points_index[i] = np.where(self.interface_gammatheta.points_index == x_i)[0]
            self.interface_alphatheta.triple_points_index[i] = np.where(self.interface_alphatheta.points_index == x_i)[0]
            try:
                self.interface_gammaalpha.ghost_triple_points_index[i] = np.where(self.interface_gammaalpha.ghost_points_index == x_i)[0]
            except:
                pass
            i = i+1

        if all(self.interface_gammaalpha.ghost_triple_points_index == -1):
            self.interface_gammaalpha.ghost_edges_index = np.zeros(0, dtype = np.int)
            self.interface_gammaalpha.ghost_n = 0
            self.interface_gammaalpha.ghost_points = np.zeros((0,2))
            self.interface_gammaalpha.ghost_points_index = np.zeros(0, dtype = np.int)
            self.interface_gammaalpha.ghost_points_index_which_param = -1
            self.interface_gammaalpha.ghost_triple_points_index = np.zeros(0, dtype = np.int)
            where_t, = np.where(self.level_set_alphatheta_enriched.phi_background > 0)
            where_ga, = np.where(self.level_set_gammaalpha_enriched.phi_background < 0)
            where_ghost = np.intersect1d(where_t, where_ga)
            for x_i in where_ghost:
                dist_x3 = la.norm(self.background_mesh.points[x_i] - self.enriched_mesh.points[self.triple_points_index], 2, axis = 1)
                self.level_set_gammaalpha_enriched.phi_background[x_i] = np.min(dist_x3)
                dist_x3 = la.norm(self.enriched_mesh.points[x_i] - self.enriched_mesh.points[self.triple_points_index], 2, axis = 1)
                self.level_set_gammaalpha_enriched.phi[x_i] = np.min(dist_x3)
#        dist_triple = np.zeros((len(self.interface_gammaalpha.ghost_points_index), i))
#        for j in range(0,i):
#            dist_triple[:,j] = la.norm(self.interface_gammaalpha.ghost_points - self.enriched_mesh.points[self.triple_points_index[j]], 2, axis = 1)
#        dist_triple = np.sum(dist_triple, axis = 1)
#        self.interface_gammaalpha.ghost_index_max_d_triple = np.argmax(dist_triple)
#        self.interface_gammaalpha.ghost_max_d_triple = np.max(la.norm(self.interface_gammaalpha.ghost_points[self.interface_gammaalpha.ghost_index_max_d_triple] - self.enriched_mesh.points[self.triple_points_index], 2, axis = 1))


        self.interface_gammaalpha.n = len(self.interface_gammaalpha.points_index)
        self.interface_gammatheta.n = len(self.interface_gammatheta.points_index)
        self.interface_alphatheta.n = len(self.interface_alphatheta.points_index)

        self.precipitate_mesh_theta.points_index = np.unique(self.precipitate_mesh_theta.triangles_points_index.flatten())
        self.diffusion_mesh_alpha.points_index = np.unique(self.diffusion_mesh_alpha.triangles_points_index.flatten())
        self.diffusion_mesh_gamma.points_index = np.unique(self.diffusion_mesh_gamma.triangles_points_index.flatten())

        self.diffusion_mesh_gamma.points = self.enriched_mesh.points[self.diffusion_mesh_gamma.points_index]
        self.diffusion_mesh_alpha.points = self.enriched_mesh.points[self.diffusion_mesh_alpha.points_index]
        self.precipitate_mesh_theta.points = self.enriched_mesh.points[self.precipitate_mesh_theta.points_index]

        self.diffusion_mesh_gamma.n = len(self.diffusion_mesh_gamma.points)
        self.diffusion_mesh_alpha.n = len(self.diffusion_mesh_alpha.points)
        self.precipitate_mesh_theta.n = len(self.precipitate_mesh_theta.points)

        self.diffusion_mesh_gamma.n_tri = len(self.diffusion_mesh_gamma.triangles_index)
        self.diffusion_mesh_alpha.n_tri = len(self.diffusion_mesh_alpha.triangles_index)


        ### Find I(i) for diffusive domains
        if update_count == 0:
            self.I_diff_gamma = np.arange(0,self.diffusion_mesh_gamma.n)
            self.I_diff_alpha = np.arange(0,self.diffusion_mesh_alpha.n)

            self.level_set_gammaalpha_enriched.FPT_value(self)
            self.level_set_alphatheta_enriched.FPT_value(self)
        else:
            where_triple_old, = np.where(self.has_point_been_shifted_old[:,1]%4 == 0)
            where_ga_old, = np.where(self.has_point_been_shifted_old[:,1] == 1)
            where_gt_old, = np.where(self.has_point_been_shifted_old[:,1] == 3)
            where_at_old, = np.where(self.has_point_been_shifted_old[:,1] == 2)
            where_ga_gamma_old = np.union1d(self.diffusion_enriched_to_gamma_old[where_ga_old], self.diffusion_enriched_to_gamma_old[where_triple_old])
            where_ga_alpha_old = np.union1d(self.diffusion_enriched_to_alpha_old[where_ga_old], self.diffusion_enriched_to_alpha_old[where_triple_old])
            where_gt_gamma_old = np.union1d(self.diffusion_enriched_to_gamma_old[where_gt_old], self.diffusion_enriched_to_gamma_old[where_triple_old])
            where_at_alpha_old = np.union1d(self.diffusion_enriched_to_alpha_old[where_at_old], self.diffusion_enriched_to_alpha_old[where_triple_old])

            self.I_diff_gamma = np.zeros(self.diffusion_mesh_gamma.n, dtype = np.int)
            self.I_diff_alpha = np.zeros(self.diffusion_mesh_alpha.n, dtype = np.int)

            for i in range(0,self.diffusion_mesh_gamma.n):
                if self.has_point_been_shifted[self.diffusion_mesh_gamma.points_index[i], 1] == 1:
                    self.I_diff_gamma[i] = where_ga_gamma_old[np.argmin(la.norm(self.diffusion_mesh_gamma.points[i]  - self.diffusion_points_old_gamma[where_ga_gamma_old], axis = 1))]
                elif self.has_point_been_shifted[self.diffusion_mesh_gamma.points_index[i], 1] == 3:
                    self.I_diff_gamma[i] = where_gt_gamma_old[np.argmin(la.norm(self.diffusion_mesh_gamma.points[i]  - self.diffusion_points_old_gamma[where_gt_gamma_old], axis = 1))]
                else:
                    self.I_diff_gamma[i] = np.argmin(la.norm(self.diffusion_mesh_gamma.points[i]  - self.diffusion_points_old_gamma, axis = 1))

            for i in range(0,self.diffusion_mesh_alpha.n):
                if self.has_point_been_shifted[self.diffusion_mesh_alpha.points_index[i], 1] == 1:
                    self.I_diff_alpha[i] = where_ga_alpha_old[np.argmin(la.norm(self.diffusion_mesh_alpha.points[i]  - self.diffusion_points_old_alpha[where_ga_alpha_old], axis = 1))]
                elif self.has_point_been_shifted[self.diffusion_mesh_alpha.points_index[i], 1] == 2:
                    self.I_diff_alpha[i] = where_at_alpha_old[np.argmin(la.norm(self.diffusion_mesh_alpha.points[i]  - self.diffusion_points_old_alpha[where_at_alpha_old], axis = 1))]
                else:
                    self.I_diff_alpha[i] = np.argmin(la.norm(self.diffusion_mesh_alpha.points[i]  - self.diffusion_points_old_alpha, axis = 1))

        #Coordinate vector from enriched points indices to diffusion mesh indices
        self.diffusion_mesh_gamma.enriched_to_gamma = -np.ones(self.enriched_mesh.n, dtype = np.int)
        self.diffusion_mesh_alpha.enriched_to_alpha = -np.ones(self.enriched_mesh.n, dtype = np.int)

        j = 0
        for i in self.diffusion_mesh_gamma.points_index:
            self.diffusion_mesh_gamma.enriched_to_gamma[i] = j
            j = j+1

        j = 0
        for i in self.diffusion_mesh_alpha.points_index:
            self.diffusion_mesh_alpha.enriched_to_alpha[i] = j
            j = j+1

        ### Parametrisation and deleting loops in ghost interface. Reinitialization is not done good enough (only for points inside and on the loop, not outside). Better to do a full reinit when this happens.
        amount_triple = len(self.triple_points_index)
        self.interface_gammaalpha.ghost_n = len(self.interface_gammaalpha.ghost_points_index)
        if self.interface_gammaalpha.ghost_edges_index.shape[0] > 0:
            self.interface_gammaalpha.parametrisation_ghost = -np.ones((int(amount_triple / 2),self.interface_gammaalpha.ghost_n))
            self.interface_gammaalpha.ghost_points_index_which_param = -np.ones(self.interface_gammaalpha.ghost_n, dtype = np.int)
            self.interface_gammaalpha.parametrisation_triple_points_index = -np.ones((int(amount_triple / 2), 2), dtype = np.int)
            self.background_mesh.t_parametrisation_ghost_fixed = -np.ones(int(amount_triple / 2))
            i = 0
            for x_i in self.triple_points_index:
                self.interface_gammaalpha.ghost_triple_points_index[i] = np.where(self.interface_gammaalpha.ghost_points_index == x_i)[0]
                i = i+1
            if amount_triple % 2 != 0:
                print('odd amount of triple points')
            else:
                triple_points_ga = self.interface_gammaalpha.ghost_triple_points_index.copy()
                triple_points_ga_enr = self.interface_gammaalpha.ghost_points_index[triple_points_ga]

                edges_ii = self.interface_gammaalpha.ghost_edges_index.copy()
                which_param_i3_deleted = np.zeros(0, dtype = np.int)
                for i3 in range(0, int(amount_triple / 2)):
                    edges = self.enriched_mesh.points[self.interface_gammaalpha.ghost_edges_index]
                    length_edges = la.norm(edges[:,0]-edges[:,1],2,axis = 1)

                    x_i_ga = triple_points_ga[0]
                    x_i = triple_points_ga_enr[0]
                    triple_points_ga = np.delete(triple_points_ga, 0)
                    triple_points_ga_enr = np.delete(triple_points_ga_enr, 0)

                    self.interface_gammaalpha.parametrisation_triple_points_index[i3,0] = x_i_ga

                    h_sum = 0
                    self.interface_gammaalpha.parametrisation_ghost[i3, x_i_ga] = h_sum
                    self.interface_gammaalpha.ghost_points_index_which_param[x_i_ga] = i3
                    i = 0
                    while all(x_i != triple_points_ga_enr) and i < self.enriched_mesh.n:
                        #Update current point
                        which_edge_i, zero_one = np.where(edges_ii == x_i)
                        x_i_ga, = np.where(self.interface_gammaalpha.ghost_points_index==x_i)
                        self.interface_gammaalpha.parametrisation_ghost[i3, x_i_ga] = h_sum
                        self.interface_gammaalpha.ghost_points_index_which_param[x_i_ga] = i3
                        if self.two_particles == None and x_i == self.background_mesh.i_ghost_fixed:
                            self.background_mesh.t_parametrisation_ghost_fixed[i3] = h_sum

                        #Look for next point. If multiple edges has end point x_i we need to delete the edges that imply odd (> 2?) parity
                        if which_edge_i.shape[0] != 1:
                            which_param_i3_deleted = np.append(which_param_i3_deleted, i3)
                            print('i ', i, 'split in interface, x_i ', x_i, 'which_edge_i ', which_edge_i)
                            edges_i_to_be_deleted = np.zeros(0, dtype = np.int)
                            for e_i in which_edge_i:
                                which_edge_i_split, zero_one_split = np.where(edges_ii == np.setdiff1d(edges_ii[e_i], x_i)[0])
                                if which_edge_i_split.shape[0] > 2:
                                    edges_i_to_be_deleted = np.append(edges_i_to_be_deleted, e_i)
                            edges_ii = np.delete(edges_ii, edges_i_to_be_deleted, 0)
                            length_edges = np.delete(length_edges, edges_i_to_be_deleted, 0)

                            new_which_edge_i = np.setdiff1d(which_edge_i, edges_i_to_be_deleted)
                            where_which_edge_i, = np.where(which_edge_i == new_which_edge_i)
                            which_edge_i, zero_one = np.where(edges_ii == x_i)

                            if self.two_particles == None:
                                possible_new_i_ghost_fixed = x_i
                                self.background_mesh.i_ghost_fixed_shifted = False

                            if which_edge_i.shape[0] != 1:
                                temp_edges_ii = edges_ii
                                x_i0 = x_i
                                j = 0
                                while all(x_i != triple_points_ga_enr) and (x_i != x_i0 or j == 0):
                                    if self.two_particles == None and x_i == self.background_mesh.i_ghost_fixed:
                                        self.background_mesh.i_ghost_fixed_shifted = True
                                    if j == 0:
                                        temp_which_edge_i = which_edge_i[0]
                                        temp_zero_one = zero_one[0]
                                    else:
                                        temp_which_edge_i, temp_zero_one = np.where(temp_edges_ii == x_i)
                                    x_i = temp_edges_ii[temp_which_edge_i, np.setdiff1d(np.arange(0,2), temp_zero_one)][0]
                                    temp_edges_ii = np.delete(temp_edges_ii, temp_which_edge_i, 0)
                                    j=j+1
                                    if j > 1e6:
                                        break
                                temp_which_edge_i, temp_zero_one = np.where(temp_edges_ii == x_i)
                                if any(x_i == triple_points_ga_enr):
                                    which_edge_i = which_edge_i[0]
                                    zero_one = zero_one[0]
                                elif x_i == x_i0:
                                    j = 0
                                    for edgeii in edges_ii[which_edge_i]:
                                        if all(np.sort(edgeii) == np.sort(temp_edges_ii[temp_which_edge_i[0]])):
                                            where_triple_direction_edges_i = j
                                        j = j+1
                                    which_edge_i = which_edge_i[where_triple_direction_edges_i]
                                    zero_one = zero_one[where_triple_direction_edges_i]
                                if self.two_particles == None and self.background_mesh.i_ghost_fixed_shifted:
                                    self.background_mesh.i_ghost_fixed = possible_new_i_ghost_fixed
                                    self.background_mesh.points[possible_new_i_ghost_fixed] = self.enriched_mesh.points[possible_new_i_ghost_fixed]
                                    where_interface_new_i_ghost, = np.where(self.interface_gammaalpha.ghost_points_index == possible_new_i_ghost_fixed)[0]
                                    self.background_mesh.t_parametrisation_ghost_fixed[i3] = self.interface_gammaalpha.parametrisation_ghost[i3, where_interface_new_i_ghost]
                                    print('fixed point moved')

                        h_sum = h_sum + length_edges[which_edge_i]
                        x_i = edges_ii[which_edge_i,np.setdiff1d(np.arange(0,2), zero_one)][0]
                        edges_ii = np.delete(edges_ii, which_edge_i,0)
                        length_edges = np.delete(length_edges, which_edge_i,0)
                        i = i+1
                    x_i_ga, = np.where(self.interface_gammaalpha.ghost_points_index == x_i)
                    self.interface_gammaalpha.parametrisation_ghost[i3, x_i_ga] = h_sum
                    self.interface_gammaalpha.ghost_points_index_which_param[x_i_ga] = i3
                    self.interface_gammaalpha.parametrisation_triple_points_index[i3,1] = x_i_ga
                    triple_points_ga = np.setdiff1d(triple_points_ga, x_i_ga)
                    triple_points_ga_enr = np.setdiff1d(triple_points_ga_enr, x_i)
                ### There is a loop
                if len(edges_ii) > 0:
                    if self.two_particles != None:
                        print('collapse needed with two particle model.')# this probably isnt working properly yet. need to find out on which ghost part it collapses')
                    deleted = np.zeros(0, dtype = np.int)
                    where_ghost_points_to_be_deleted, =  np.where(self.interface_gammaalpha.ghost_points_index_which_param == -1)

                    ghost_points_to_be_deleted = self.interface_gammaalpha.ghost_points_index[where_ghost_points_to_be_deleted]
                    self.level_set_gammaalpha_enriched.phi[ghost_points_to_be_deleted] = la.norm(self.enriched_mesh.points[ghost_points_to_be_deleted] - self.background_mesh.points[self.background_mesh.i_ghost_fixed], 2, axis = 1)
                    where_background_ghost_points_to_be_deleted, = np.where(ghost_points_to_be_deleted < self.N)
                    self.level_set_gammaalpha_enriched.phi_background[ghost_points_to_be_deleted[where_background_ghost_points_to_be_deleted]] = self.level_set_gammaalpha_enriched.phi[ghost_points_to_be_deleted[where_background_ghost_points_to_be_deleted]]
                    where_ghost_neg = np.intersect1d(np.where(self.level_set_gammaalpha_enriched.phi < 0)[0], self.precipitate_mesh_theta.points_index)
                    for i in where_ghost_neg:
                        amount_ghost_delete = 0
                        amount_ghost_stay = 0
                        amount_ghost = 0
                        search = i
                        searched = i
                        jj = 0
                        while amount_ghost < 2 and jj < 1e5:
                            patch = np.setdiff1d(np.unique(self.enriched_mesh.triangles_points_index[self.enriched_mesh.point_in_tri[search].nonzero()[1]].flatten()), searched)
                            where_shifted_ghost, = np.where(self.has_point_been_shifted[patch, 1] == 11)
                            amount_ghost_delete = amount_ghost_delete + len(np.where(self.level_set_gammaalpha_enriched.phi[patch[where_shifted_ghost]] > 0)[0])
                            amount_ghost_stay = amount_ghost_stay + len(np.where(self.level_set_gammaalpha_enriched.phi[patch[where_shifted_ghost]] == 0)[0])
                            search = np.setdiff1d(patch, search)
                            searched = np.hstack((searched, patch))
                            amount_ghost = amount_ghost_delete + amount_ghost_stay
                            jj = jj + 1
                        if amount_ghost_stay > 1 and amount_ghost_delete > 1:
                            print('point i ', i, 'has both stay as delete points? count stay/delete ', amount_ghost_stay, amount_ghost_delete)
                        if amount_ghost_delete > 0:
                            self.level_set_gammaalpha_enriched.phi[i] = la.norm(self.enriched_mesh.points[i] - self.background_mesh.points[self.background_mesh.i_ghost_fixed], 2)
                            if i < self.N:
                                self.level_set_gammaalpha_enriched.phi_background[i] = self.level_set_gammaalpha_enriched.phi[i]
                            deleted = np.append(deleted, i)

                    i = 0
                    edges_to_be_kept = np.zeros(0, dtype = np.int)
                    for edgeii in self.interface_gammaalpha.ghost_edges_index:
                        if all(self.level_set_gammaalpha_enriched.phi[edgeii] == 0):
                            edges_to_be_kept = np.append(edges_to_be_kept, i)
                        i = i+1
                    self.interface_gammaalpha.ghost_edges_index = self.interface_gammaalpha.ghost_edges_index[edges_to_be_kept]
                    if not(all(self.interface_gammaalpha.parametrisation_ghost[i3, where_ghost_points_to_be_deleted] < 0)):
#                        print('ghost points with phi = 0 are deleted')
                        self.interface_gammaalpha.parametrisation_ghost[i3, where_ghost_points_to_be_deleted] = -2

        ### Calculate normal vectors
        self.n_ga = np.zeros((self.enriched_mesh.n,2))
        self.n_t  = np.zeros((self.enriched_mesh.n,2))
        self.enriched_mesh.patch_matrix = lil_matrix((self.enriched_mesh.n, self.enriched_mesh.n))
        self.enriched_mesh.three_neighbours = lil_matrix((self.enriched_mesh.n, self.enriched_mesh.n), dtype = np.int)
        BP_points = np.zeros(0, dtype = np.int)
        for j in range(0,self.enriched_mesh.n):
            if self.has_point_been_shifted[j,0] == 1:# or j in where_interface_points:
                patch3 = j
                for i in range(0,3):
                    patch_new = self.enriched_mesh.triangles_points_index[self.enriched_mesh.point_in_tri[patch3].nonzero()[1]].flatten()
                    patch3 = np.unique(np.append(patch3, patch_new))
                    new_patch3 = np.setdiff1d(patch3, self.enriched_mesh.three_neighbours[j].nonzero()[1])
                    self.enriched_mesh.three_neighbours[j, new_patch3] = i+1
            if self.is_point_BP[j,0] == 0:
                xp = self.enriched_mesh.points[j]
                other_ii = np.unique(self.enriched_mesh.triangles_points_index[self.enriched_mesh.point_in_tri[j].nonzero()[1]].flatten())
                other_i = self.enriched_mesh.points[other_ii]
                hp = np.max(la.norm(other_i - xp, axis = 1))
                n_row = len(other_ii)
                if n_row < patch_size:
                    r = 2
                    new_other_ii = other_ii.copy()
                    while n_row < patch_size:
                        for l in range(0,len(new_other_ii)):
                            for tri_i in self.enriched_mesh.point_in_tri[new_other_ii[l]].nonzero():
                                trii = self.enriched_mesh.triangles_points_index[tri_i]
                                for i in np.setdiff1d(trii, new_other_ii[l]):
                                    if la.norm(self.enriched_mesh.points[i] - xp) <= r * hp:
                                        other_ii = np.append(other_ii, i)

                        other_ii = np.unique(other_ii)
                        new_other_ii = other_ii.copy()
                        n_row = len(other_ii)

                        if r > 20:
                            print('grad phi calc needed far too many iterations at point ', xp, 'index enriched ', j, 'new points ', new_other_ii)
                            break
                        r = r+1
                    if not(len(other_ii) - len(np.unique(other_ii)) == 0):
                        print('other_ii not made unique in grad phi calc', other_ii)
                other_i = self.enriched_mesh.points[other_ii]
                eta = (other_i - xp)/hp
                M_eta = np.ones((n_row, 6))
                phi_ga = np.zeros(n_row)
                phi_t  = np.zeros(n_row)
                for i in range(0,n_row):
                    etaj = eta[i]
                    M_eta[i,1:6] = np.array([etaj[0], etaj[1], etaj[0]**2, etaj[0] * etaj[1], etaj[1]**2])
                    phi_ga[i] = self.level_set_gammaalpha_enriched.phi[other_ii[i]]
                    phi_t[i]  = self.level_set_alphatheta_enriched.phi[other_ii[i]]
                #other_ii + 1 as 0 won't be stored. we only use self.patch_matrix.nonzero()[1] to see what neighbours are!!
                self.enriched_mesh.patch_matrix[j, other_ii] = other_ii+1
                self.enriched_mesh.patch_matrix[j, j] = hp
                B_ga = la.lstsq(M_eta, phi_ga)[0][[1,2]]
                B_t  = la.lstsq(M_eta, phi_t )[0][[1,2]]
                self.n_ga[j] = B_ga/la.norm(B_ga)
                self.n_t[j]  = B_t /la.norm(B_t)
            else:
                BP_points = np.append(BP_points, j)


        for j in BP_points:
            xp = self.enriched_mesh.points[j]
            other_ii = np.unique(self.enriched_mesh.triangles_points_index[self.enriched_mesh.point_in_tri[j].nonzero()[1]].flatten())
            other_i = self.enriched_mesh.points[other_ii]
            hp = np.max(la.norm(other_i - xp, axis = 1))
            n_row = len(other_ii)
            has_internal = any(self.is_point_BP[other_ii,1] == 0)
            new_other_ii = other_ii.copy()
            r = 2
            while not(has_internal):
                old_other_ii = other_ii.copy()
                for l in range(0,len(new_other_ii)):
                    for tri_i in self.enriched_mesh.point_in_tri[new_other_ii[l]].indices:
                        trii = self.enriched_mesh.triangles_points_index[tri_i]
                        for i in np.setdiff1d(trii, new_other_ii[l]):
                            if la.norm(self.enriched_mesh.points[i] - xp, 2) <= r * hp:
                                other_ii = np.append(other_ii, i)

                new_other_ii = np.setdiff1d(other_ii ,old_other_ii)
                has_internal = any(self.is_point_BP[new_other_ii,1] == 0)
                r=r+1

            where_internal = np.where(self.is_point_BP[other_ii,0] == 0)
            other_ii = np.union1d(other_ii, self.enriched_mesh.patch_matrix[other_ii[where_internal]].nonzero()[1])
            n_row = len(other_ii)
            if not(n_row - len(np.unique(other_ii)) == 0):
                print('other_ii not made unique in grad phi calc', other_ii)
            other_i = self.enriched_mesh.points[other_ii]
            eta = (other_i - xp)/hp
            M_eta = np.ones((n_row, 6))
            phi_ga = np.zeros(n_row)
            phi_t  = np.zeros(n_row)
            for i in range(0,n_row):
                etaj = eta[i]
                M_eta[i,1:6] = np.array([etaj[0], etaj[1], etaj[0]**2, etaj[0] * etaj[1], etaj[1]**2])
                phi_ga[i] = self.level_set_gammaalpha_enriched.phi[other_ii[i]]
                phi_t[i]  = self.level_set_alphatheta_enriched.phi[other_ii[i]]
            self.enriched_mesh.patch_matrix[j, other_ii] = other_ii+1
            self.enriched_mesh.patch_matrix[j, j] = hp
            B_ga = la.lstsq(M_eta, phi_ga)[0][[1,2]]
            B_t  = la.lstsq(M_eta, phi_t )[0][[1,2]]
            self.n_ga[j] = B_ga/la.norm(B_ga)
            self.n_t[j]  = B_t /la.norm(B_t)


        if np.abs(np.sum(np.abs(self.enriched_mesh.area_triangle)) - (self.xN-self.x0)*(self.yN-self.y0)) > 1e-10:
            print('area enriched mesh triangles not ok', np.sum(np.abs(self.enriched_mesh.area_triangle)))


        ### I think this isn't used anymore. Is used in reinitialization to apply Dirichlet condition and handled there
        self.background_mesh.Tau = self.background_mesh.Tau[self.background_mesh.Tau.getnnz(1)>0]

        self.interface_gammaalpha.Shifted_points = np.zeros((0), dtype = np.int)
        self.interface_gammaalpha.Shifted_points_ghost = np.zeros((0), dtype = np.int)
        self.interface_gammatheta.Shifted_points = np.zeros((0), dtype = np.int)
        self.interface_alphatheta.Shifted_points = np.zeros((0), dtype = np.int)
        for i in range(0,self.background_mesh.Tau.shape[0]):
            x_ii = int(self.background_mesh.Tau[i,-1])
            if self.has_point_been_shifted[x_ii, 1]%4 == 0:
                self.interface_gammaalpha.Shifted_points = np.append(self.interface_gammaalpha.Shifted_points, i)
                self.interface_gammaalpha.Shifted_points_ghost = np.append(self.interface_gammaalpha.Shifted_points_ghost, i)
                self.interface_gammatheta.Shifted_points = np.append(self.interface_gammatheta.Shifted_points, i)
            elif self.has_point_been_shifted[x_ii, 1] == 1:
                self.interface_gammaalpha.Shifted_points = np.append(self.interface_gammaalpha.Shifted_points, i)
            elif self.has_point_been_shifted[x_ii, 1] == 11:
                self.interface_gammaalpha.Shifted_points_ghost = np.append(self.interface_gammaalpha.Shifted_points_ghost, i)
            elif self.has_point_been_shifted[x_ii, 1] == 3:
                self.interface_gammatheta.Shifted_points = np.append(self.interface_gammatheta.Shifted_points, i)
            elif self.has_point_been_shifted[x_ii, 1] == 2:
                self.interface_alphatheta.Shifted_points = np.append(self.interface_alphatheta.Shifted_points, i)

        if self.two_particles == None and self.background_mesh.i_ghost_fixed != -1:
            self.level_set_gammaalpha_enriched.phi_background[self.background_mesh.i_ghost_fixed] = 0





    def find_triple(self, phi_ga, phi_at):
        new_x3 = np.zeros((0,2))
        shiftbendcut_tri_i = np.zeros((0,2), dtype = np.int)
        which_triple_bend = np.zeros((0,2))
        for i in range(0,self.background_mesh.n_tri):
            trii = self.background_mesh.triangles_points_index[i]
            tri  = self.background_mesh.points[trii]

            ga_at = 0
            ga = 0
            at = 0
            amount_shift_ga = 0
            amount_shift_at = 0
            for edgei in np.array([[0,1],[0,2],[1,2]]):
                edgeii = trii[edgei]
                edge = tri[edgei]
                j = self.background_mesh.edge_to_index[edgeii[0], edgeii[1]]
                ga_tri = phi_ga[edgeii[0]] * phi_ga[edgeii[1]] < 0
                at_tri = phi_at[edgeii[0]] * phi_at[edgeii[1]] < 0
                if ga_tri:
                    taue_ga = -phi_ga[edgeii[0]]/(phi_ga[edgeii[1]] - phi_ga[edgeii[0]])
                    pe_ga = (1-taue_ga)*edge[0] + taue_ga*edge[1]
                    e0_delta_ga = taue_ga > self.delta
                    e1_delta_ga = taue_ga < 1 - self.delta
                    if not(e0_delta_ga):
                        amount_shift_ga = amount_shift_ga + 1
                        if amount_shift_ga == 1:
                            p0_index_ga = edgeii[0]
                        elif amount_shift_ga == 2:
                            p1_index_ga = edgeii[0]
                    elif not(e1_delta_ga):
                        amount_shift_ga = amount_shift_ga + 1
                        if amount_shift_ga == 1:
                            p0_index_ga = edgeii[1]
                        elif amount_shift_ga == 2:
                            p1_index_ga = edgeii[1]
                if at_tri:
                    taue_at = -phi_at[edgeii[0]]/(phi_at[edgeii[1]] - phi_at[edgeii[0]])
                    pe_at = (1-taue_at)*edge[0] + taue_at*edge[1]
                    e0_delta_at = taue_at > self.delta
                    e1_delta_at = taue_at < 1 - self.delta
                    if not(e0_delta_at):
                        amount_shift_at = amount_shift_at + 1
                        if amount_shift_at == 1:
                            p0_index_at = edgeii[0]
                        elif amount_shift_at == 2:
                            p1_index_at = edgeii[0]
                    elif not(e1_delta_at):
                        amount_shift_at = amount_shift_at + 1
                        if amount_shift_at == 1:
                            p0_index_at = edgeii[1]
                        elif amount_shift_at == 2:
                            p1_index_at = edgeii[1]
                if ga_tri and at_tri:
                    ga_at = ga_at + 1
                    if ga_at == 1:
                        p02_ga = pe_ga
                        p02_at = pe_at
                        taue02_ga = taue_ga
                        taue02_at = taue_at
                        j02 = j
                        e02 = edgeii
                    elif ga_at == 2:
                        p12_ga = pe_ga
                        p12_at = pe_at
                        taue12_ga = taue_ga
                        taue12_at = taue_at
                        j12 = j
                        e12 = edgeii
                    else:
                        print('3 cross triangle? ',ga_at)
                elif ga_tri or at_tri:
                    if ga_tri:
                        ga = ga + 1
                        if ga == 1:
                            p01_ga = pe_ga
                            taue01_ga = taue_ga
                            j01_ga = j
                            e01_ga = edgeii
                        elif ga == 2:
                            p11_ga = pe_ga
                            taue12_ga = taue_ga
                            j11_ga = j
                            e11_ga = edgeii
                    if at_tri:
                        at = at + 1
                        if at == 1:
                            p01_at = pe_at
                            taue01_at = taue_at
                            j01_at = j
                            e01_at = edgeii
                        elif at == 2:
                            p11_at = pe_at
                            taue11_at = taue_at
                            j11_at = j
                            e11_at = edgeii

            #If triangle has a point where phi < 0 and phi > 0, the interface has to be crossing this triangle
            ga_intersect = any(phi_ga[trii] > 0) and any(phi_ga[trii] < 0)
            at_intersect = any(phi_at[trii] > 0) and any(phi_at[trii] < 0)
            #Also when two points of a triangle have phi = 0, the interface is crossing this triangle through this edge
            where_ga, = np.where(phi_ga[trii] == 0)
            where_at, = np.where(phi_at[trii] == 0)

            #Points can be shifted in the triangle, so phi = 0. Check this by looking at has_point_been_shifted
            if where_ga.shape[0] == 2 and where_at.shape[0] != 2:
                edge_ga = np.sort(trii[where_ga])
                j_ga_edge = self.background_mesh.edge_to_index[edge_ga[0], edge_ga[1]]
                other_tri_i = np.setdiff1d(self.background_mesh.edge_in_tri[j_ga_edge], i)[0]
                if self.has_point_been_shifted[np.setdiff1d(self.background_mesh.triangles_points_index[other_tri_i], edge_ga), 1]%4 != 0:
                    ga_intersect = True
            if where_at.shape[0] == 2 and where_ga.shape[0] != 2:
                edge_at = np.sort(trii[where_at])
                j_at_edge = self.background_mesh.edge_to_index[edge_at[0], edge_at[1]]
                other_tri_i = np.setdiff1d(self.background_mesh.edge_in_tri[j_at_edge], i)[0]
                if self.has_point_been_shifted[np.setdiff1d(self.background_mesh.triangles_points_index[other_tri_i], edge_at)[0], 1]%4 != 0:
                    at_intersect = True

            if ga_intersect and at_intersect:
                #Both interfaces cut one similar edge
                if ga_at == 1:
                    #Both interfaces cut other two edges
                    if ga + at == 2:
                        pass
                    #One interface cut edge, other interface goes through corner.
                    elif ga + at == 1:
                        if ga == 0:
                            where_p01_ga_index, = np.where(phi_ga[trii] == 0)
                            p01_ga_index = trii[where_p01_ga_index[0]]
                            p01_ga = tri[where_p01_ga_index][0]
                        elif at == 0:
                            where_p01_at_index, = np.where(phi_at[trii] == 0)
                            p01_at_index = trii[where_p01_at_index][0]
                            p01_at = tri[where_p01_at_index][0]
                    #Both interfaces go through a corner
                    elif ga + at == 0:
                        where_p01_ga_index, = np.where(phi_ga[trii] == 0)
                        p01_ga_index = trii[where_p01_ga_index[0]]
                        p01_ga = tri[where_p01_ga_index][0]
                        where_p01_at_index, = np.where(phi_at[trii] == 0)
                        p01_at_index = trii[where_p01_at_index][0]
                        p01_at = tri[where_p01_at_index][0]
                    X = np.array( [[p02_ga[0] - p01_ga[0], p01_at[0] - p02_at[0]],
                                   [p02_ga[1] - p01_ga[1], p01_at[1] - p02_at[1]]] )
                    if la.det(X) != 0:
                        t = la.solve( X, np.array( [p01_at[0] - p01_ga[0], p01_at[1] - p01_ga[1]] ) )
                    else:
#                        print('interfaces parallel, X singular')  #(parallel lines)
                        t = np.ones(2) * np.inf
                #Both interfaces cut the same two edges
                elif ga_at == 2:
                    X =np.array( [[p02_ga[0] - p12_ga[0], p12_at[0] - p02_at[0]],
                                  [p02_ga[1] - p12_ga[1], p12_at[1] - p02_at[1]]] )
                    if la.det(X) != 0:
                        t = la.solve( X, np.array( [ p12_at[0] - p12_ga[0], p12_at[1] - p12_ga[1] ] ) )
                    else:
#                        print('interfaces parallel, X singular')
                        t = np.ones(2) * np.inf
                #One interface goes through a corner and both interfaces cut different edges
                elif ga_at == 0 and ga + at == 3:
                    if ga == 1:
                        where_p11_ga_index, = np.where(phi_ga[trii] == 0)
                        p11_ga_index = trii[where_p11_ga_index][0]
                        p11_ga = tri[where_p11_ga_index][0]
                    elif at == 1:
                        where_p11_at_index, = np.where(phi_at[trii] == 0)
                        p11_at_index = trii[where_p11_at_index][0]
                        p11_at = tri[where_p11_at_index][0]
                    X = np.array( [[p01_ga[0] - p11_ga[0], p11_at[0] - p01_at[0]],
                                             [p01_ga[1] - p11_ga[1], p11_at[1] - p01_at[1]]] )
                    if la.det(X) != 0:
                        t = la.solve( X, np.array(  [p11_at[0] - p11_ga[0], p11_at[1] - p11_ga[1] ] ) )
                    else:
#                            print('interfaces parallel, X singular')
                        t = np.ones(2) * np.inf
                #Both interfaces go through a corner and both interfaces cut different edges
                elif ga_at == 0:
                    #Both cut ones and go through corner ones
                    if ga == 1 and at == 1:
                        where_p11_ga_index, = np.where(phi_ga[trii] == 0)
                        p11_ga_index = trii[where_p11_ga_index][0]
                        p11_ga = tri[where_p11_ga_index][0]
                        where_p11_at_index, = np.where(phi_at[trii] == 0)
                        p11_at_index = trii[where_p11_at_index][0]
                        p11_at = tri[where_p11_at_index][0]
                    #gamma/alpha goes through two corners and theta goes through two edges
                    elif ga == 0 and at == 2:
                        where_p01_ga_index, = np.where(phi_ga[trii] == 0)
                        p01_ga_index = trii[where_p01_ga_index][0]
                        p11_ga_index = trii[where_p01_ga_index][1]
                        p01_ga = tri[where_p01_ga_index][0]
                        p11_ga = tri[where_p01_ga_index][1]
                    #theta goes through two corners and gamma/alpha goes through two edges
                    elif at == 0 and ga == 2:
                        where_p01_at_index, = np.where(phi_at[trii] == 0)
                        p01_at_index = trii[where_p01_at_index][0]
                        p11_at_index = trii[where_p01_at_index][1]
                        p01_at = tri[where_p01_at_index][0]
                        p11_at = tri[where_p01_at_index][1]
                    elif ga == 1 and at == 0:
                        where_p01_at_index, = np.where(phi_at[trii] == 0)
                        p01_at_index = trii[where_p01_at_index][0]
                        p11_at_index = trii[where_p01_at_index][1]
                        p01_at = tri[where_p01_at_index][0]
                        p11_at = tri[where_p01_at_index][1]
                        where_p01_ga_index, = np.where(phi_ga[trii] == 0)
                        p11_ga_index = trii[where_p01_ga_index][0]
                        p11_ga = tri[where_p01_ga_index][0]
                    elif ga == 0 and at == 1:
                        where_p01_at_index, = np.where(phi_at[trii] == 0)
                        p11_at_index = trii[where_p01_at_index][0]
                        p11_at = tri[where_p01_at_index][0]
                        where_p01_ga_index, = np.where(phi_ga[trii] == 0)
                        p01_ga_index = trii[where_p01_ga_index][0]
                        p11_ga_index = trii[where_p01_ga_index][1]
                        p01_ga = tri[where_p01_ga_index][0]
                        p11_ga = tri[where_p01_ga_index][1]
                    X = np.array( [[p01_ga[0] - p11_ga[0], p11_at[0] - p01_at[0]],
                                   [p01_ga[1] - p11_ga[1], p11_at[1] - p01_at[1]]] )
                    if la.det(X) != 0:
                        t = la.solve( X, np.array(  [p11_at[0] - p11_ga[0], p11_at[1] - p11_ga[1] ] ) )
                    else:
                        t = np.ones(2) * np.inf
                else:
                    print('something weird with double cross triangles')

                if all(t >= 0) and all(t <= 1) and not(all(np.sort(t) == np.array([0,1]))) and not(all(t == np.zeros(2))) and not(all(t == np.ones(2))):
                    if ga_at == 1:
                        x_ga = (1-t[0]) * p01_ga + t[0] * p02_ga
                        x_at = (1-t[1]) * p01_at + t[1] * p02_at
                    elif ga_at == 2:
                        x_ga = (1-t[0]) * p12_ga + t[0] * p02_ga
                        x_at = (1-t[1]) * p12_at + t[1] * p02_at
                    elif ga_at == 0:
                        x_ga = (1-t[0]) * p11_ga + t[0] * p01_ga
                        x_at = (1-t[1]) * p11_at + t[1] * p01_at
                    if la.norm(x_ga - x_at) > 1e-14:
                        print('triple point not accurate, x_ga ', x_ga, 'x_at ', x_at)

                    new_x3 = np.vstack((new_x3, x_ga))

                    #In stead of looking at each corner, calculate barycentric lambda, which is same as taue_xk
                    lambda_barycentric = la.solve( np.array([ [tri[0,0], tri[1,0], tri[2,0]],
                                                              [tri[0,1], tri[1,1], tri[2,1]],
                                                              [1       , 1       , 1       ] ]), np.array([ x_ga[0], x_ga[1], 1]))

                    where_lambda_smaller_other_delta, = np.where(lambda_barycentric < self.delta) #diamond cut off delta
                    #triple shift
                    if where_lambda_smaller_other_delta.shape[0] == 2:
                        shiftbendcut_tri_i = np.vstack((shiftbendcut_tri_i, np.array([i, 4])))
#                        shift_tri_i = np.append(shift_tri_i, i)
                    elif where_lambda_smaller_other_delta.shape[0] == 1:
                        #Because bend 010 and 020 will be detected in two triangles (triple point on an edge) we will only add one of the two triangles
                        if all(la.norm(which_triple_bend - x_ga, 2, axis = 1) > 1e-10):
                            shiftbendcut_tri_i = np.vstack((shiftbendcut_tri_i, np.array([i, 12])))
#                            bend_tri_i = np.append(bend_tri_i, i)
                            which_triple_bend = np.vstack((which_triple_bend, x_ga))
                            if ga_at == 1:
                                if ga == 1 and at == 1: #bend 111, can only bend over e02
                                    other_tri_i = np.setdiff1d(self.background_mesh.edge_in_tri[j02], i)[0]
                                elif ga == 0: #then at must be 1 bend 101
                                    if lambda_barycentric[np.where(trii == np.setdiff1d(e02, e01_at)[0])][0] < self.delta: #then bend to e01_at
                                        other_tri_i = np.setdiff1d(self.background_mesh.edge_in_tri[j01_at], i)[0]
                                    elif lambda_barycentric[np.where(trii == p01_ga_index)[0]] < self.delta: #then bend to e02
                                        other_tri_i = np.setdiff1d(self.background_mesh.edge_in_tri[j02], i)[0]
                                    elif lambda_barycentric[np.where(trii == np.intersect1d(e02, e01_at)[0])[0]] < self.delta: #then bend to other edge
                                        e_other = np.sort([p01_ga_index, np.setdiff1d(e02, e01_at)[0]])
                                        j_other = self.background_mesh.edge_to_index[e_other[0],e_other[1]]
                                        other_tri_i = np.setdiff1d(self.background_mesh.edge_in_tri[j_other], i)[0]
                                elif at == 0: #ga == 1  bend 110
                                    if trii[where_lambda_smaller_other_delta][0] == p01_at_index: #then triple point shifts on e02
                                        other_tri_i = np.setdiff1d(self.background_mesh.edge_in_tri[j02], i)[0]
                                    elif trii[where_lambda_smaller_other_delta][0] == np.setdiff1d(e02, e01_ga)[0]: #triple on e01_ga
                                        other_tri_i = np.setdiff1d(self.background_mesh.edge_in_tri[j01_ga], i)[0]
                                    elif trii[where_lambda_smaller_other_delta][0] == np.intersect1d(e02, e01_ga)[0]: #triple on third edge
                                        e_other = np.sort([p01_at_index, np.setdiff1d(e02, e01_ga)[0]])
                                        j_other = self.background_mesh.edge_to_index[e_other[0],e_other[1]]
                                        other_tri_i = np.setdiff1d(self.background_mesh.edge_in_tri[j_other], i)[0]
                            elif ga_at == 2: #bend 200
                                #have to find out which edge it shifts to as two edges have both interfaces crossing
                                if lambda_barycentric[np.where(trii == np.setdiff1d(trii, e02)[0])[0]] < self.delta: #then e02 is the edge triple point shifts to
                                    j2_shift = j02
                                elif lambda_barycentric[np.where(trii == np.setdiff1d(trii, e12)[0])[0]] < self.delta: #e12
                                    j2_shift = j12
                                else:
#                                    print('bend edge on other edge, should not be possible (?). IN  def find_triple')
                                    edgeii_other = np.sort(np.setdiff1d(trii, np.intersect1d(e02, e12)))
                                    j2_shift = self.background_mesh.edge_to_index[edgeii_other[0], edgeii_other[1]]
                                other_tri_i = np.setdiff1d(self.background_mesh.edge_in_tri[j2_shift], i)[0]
                            elif ga_at == 0:
                                if ga == 1 and at == 1: #bend 011
                                    if lambda_barycentric[np.where(trii == p11_at_index)[0]] < self.delta: #then e01_at is the edge triple point shifts to
                                        other_tri_i = np.setdiff1d(self.background_mesh.edge_in_tri[j01_at], i)[0]
                                    elif lambda_barycentric[np.where(trii == p11_ga_index)[0]] < self.delta: #then e01_ga is the edge triple point shifts to
                                        other_tri_i = np.setdiff1d(self.background_mesh.edge_in_tri[j01_ga], i)[0]
                                    elif lambda_barycentric[np.where(trii == np.intersect1d(e01_ga, e01_at)[0])[0]] < self.delta: #then e_other is the edge triple point shifts to
                                        e_other = np.sort([p11_ga_index, p11_at_index])
                                        j_other = self.background_mesh.edge_to_index[e_other[0],e_other[1]]
                                        other_tri_i = np.setdiff1d(self.background_mesh.edge_in_tri[j_other], i)[0]
                                elif ga == 1 and at == 2: #bend 012
                                    if lambda_barycentric[np.where(trii == np.intersect1d(e01_at, e01_ga)[0])[0]] > self.delta: #then e01_at is the edge triple point shifts to
                                        j1_shift = j01_at
                                    else:
                                        j1_shift = j11_at
                                    other_tri_i = np.setdiff1d(self.background_mesh.edge_in_tri[j1_shift], i)[0]
                                elif ga == 2 and at == 1: #bend 021
                                    if lambda_barycentric[np.where(trii == np.intersect1d(e11_ga, e01_at)[0])[0]] < self.delta: #then e01_ga is the edge triple point shifts to
                                        j1_shift = j01_ga
                                    elif lambda_barycentric[np.where(trii == np.intersect1d(e01_ga, e01_at)[0])[0]] < self.delta: #then e11_ga is the edge triple point shifts to
                                        j1_shift = j11_ga
                                    else:
#                                        print('bend 021 to p01at edge, not really possible. especially with numerical inaccuracy. both ga points have exactly tau = delta. IN  def find_triple')
                                        e_other = np.sort(np.setdiff1d(trii, np.intersect1d(e01_ga, e11_ga)))
                                        j1_shift = self.background_mesh.edge_to_index[e_other[0], e_other[1]]
                                #When the triple point is on an edge of an interface
                                elif ga + at == 1:
                                    if ga == 1: #bend 010
                                        other_tri_i = np.setdiff1d(self.background_mesh.edge_in_tri[j01_ga], i)[0]
                                    else: #bend 001
                                        other_tri_i = np.setdiff1d(self.background_mesh.edge_in_tri[j01_at], i)[0]
                            elif ga == 2 and at == 0: #bend 020
                                if la.norm(x_ga - p01_ga) < 1e-13:
                                    j1_shift = j01_ga
                                elif la.norm(x_ga - p11_ga) < 1e-13:
                                    j1_shift = j11_ga
                                else:
#                                    print('p_ga = x_ga should be cutting p_at edge p01_ga, p11_ga x_ga ', p01_ga, p11_ga, x_ga, 'IN def find_triple')
                                    e_other = np.sort(np.setdiff1d(trii, np.intersect1d(e01_ga, e11_ga)))
                                    shift = self.background_mesh.edge_to_index[e_other[0], e_other[1]]
                                other_tri_i = np.setdiff1d(self.background_mesh.edge_in_tri[j1_shift], i)[0]
                            elif ga == 0 and at == 2: #bend 002
                                if la.norm(x_ga - p01_at) < 1e-13:
                                    j1_shift = j01_at
                                elif la.norm(x_ga - p11_at) < 1e-13:
                                    j1_shift = j11_at
                                else:
                                    print('p_ga = x_at should be cutting p_ga edge p01_at, p11_at x_ga ', p01_at, p11_at, x_ga, 'IN def ffind_triple')
                                other_tri_i = np.setdiff1d(self.background_mesh.edge_in_tri[j1_shift], i)[0]
                            elif ga == 0 and at == 1: #bend 001
                                 other_tri_i = np.setdiff1d(self.background_mesh.edge_in_tri[j01_at], i)[0]
#                            bend_on_other_tri_i = np.append(bend_on_other_tri_i, other_tri_i)
                    #cut
                    elif where_lambda_smaller_other_delta.shape[0] == 0:
#                        cut_tri_i = np.append(cut_tri_i, i)
                        shiftbendcut_tri_i = np.vstack((shiftbendcut_tri_i, np.array([i, 4])))
                    else:
                        print('error in barycentric coordinates, two lambda < delta')
                        print(where_lambda_smaller_other_delta, lambda_barycentric, trii, tri)
                        shiftbendcut_tri_i = np.vstack((shiftbendcut_tri_i, np.array([i, 16])))

        return new_x3, shiftbendcut_tri_i



    def shift(self, triangles_points_index, which_tri, old_points, Is_point_BP, old_phi, which_phi):
        if which_phi == 1:
            other_old_phi = self.level_set_alphatheta_enriched.phi.copy()
        elif which_phi == 2:
            other_old_phi = self.level_set_gammaalpha_enriched.phi.copy()

        interface_where_index_new_point = np.zeros((0),dtype=np.int)
        for i in range(0,len(which_tri)):
            trii = triangles_points_index[which_tri[i]]
            tri = old_points[trii]
            ga_no_shift = True
#            #if all points of the triangle are in the overlap, then dont shift. Otherwise do (cause of edge bending purposes) THIS HAS BEEN REMOVED AS WE NEED GHOST POINTS ON GA TOO
#            if which_phi == 1 and all(other_old_phi[trii] > 0):
#                ga_no_shift = False
            pii = 0
            amount_new = 0
            amount_shift = 0
            for edgei in np.array([[0,1],[0,2],[1,2]]):
                edge = tri[edgei]
                edgeii = trii[edgei]
                B_edge = False

                #check if edge intersects interface
                if old_phi[edgeii[0]] * old_phi[edgeii[1]] < 0 and ga_no_shift:
                    pii = pii + 1
                    taue = -old_phi[edgeii[0]]/(old_phi[edgeii[1]] - old_phi[edgeii[0]])
                    pe = (1-taue)*edge[0] + taue*edge[1]
                    #Delta stuff
                    e0_delta = taue > self.delta
                    e1_delta = taue < 1-self.delta
                    e0e1_delta = e0_delta and e1_delta
                    #Not able to shift if edge is not BE
                    if any(Is_point_BP[edgeii,0] == 1) and not(all(Is_point_BP[edgeii,0] == 1)):
                        if Is_point_BP[edgeii[0],0] == 1 and not(e0_delta):
                            B_edge = True
                        elif Is_point_BP[edgeii[1],0] == 1 and not(e1_delta):
                            B_edge = True

                    #Not able to shift if edge is connected between two different outer boundaries
                    if all(Is_point_BP[edgeii,0] == 1) and not(Is_point_BP[edgeii[0],1] == Is_point_BP[edgeii[1],1]) and all(Is_point_BP[edgeii,1] < 5):
                        B_edge = True

                    #Not able to shift if point of edge is cornerpoint
                    if any(Is_point_BP[edgeii,1] == 5):
                        if Is_point_BP[edgeii[0],1] == 5 and not(e0_delta):
                            B_edge = True
                        elif Is_point_BP[edgeii[1],1] == 5 and not(e1_delta):
                            B_edge = True

                    #Not able to shift if point of edge is already shifted to another interface
                    if which_phi == 2: #alpha theta
                        if self.has_point_been_shifted[edgeii[0],0] == 1 and not(e0_delta) and not(any(self.has_point_been_shifted[edgeii[0],1] == [2, 3])):
                            B_edge = True
                        elif self.has_point_been_shifted[edgeii[1],0] == 1  and not(e1_delta) and not(any(self.has_point_been_shifted[edgeii[1],1] == [2, 3])):
                            B_edge = True
                    else: #gamma alpha
                        if self.has_point_been_shifted[edgeii[0],0] == 1 and not(e0_delta) and not(self.has_point_been_shifted[edgeii[0],1]%10 == 1):
                            B_edge = True
                        elif self.has_point_been_shifted[edgeii[1],0] == 1  and not(e1_delta) and not(self.has_point_been_shifted[edgeii[1],1]%10 == 1):
                            B_edge = True


                    if B_edge or e0e1_delta:
                        amount_new = amount_new + 1
                        if amount_new == 1:
                            p0_new = pe
                        elif amount_new == 2:
                            p1_new = pe
                    elif not(e0_delta):
                        if la.norm(self.enriched_mesh.points[edgeii[0]] - old_points[edgeii[0]]) == 0:
                            amount_shift = amount_shift + 1
                            self.enriched_mesh.points[edgeii[0]] = pe
                            self.background_mesh.Tau[edgeii[0], edgeii] = np.array([1-taue, taue])
                            self.background_mesh.Tau[edgeii[0], self.background_mesh.n] = edgeii[0]
                            if which_phi == 1:
                                self.level_set_gammaalpha_enriched.phi[edgeii[0]] = 0
                                self.level_set_alphatheta_enriched.phi[edgeii[0]] = (1 - taue) * other_old_phi[edgeii[0]] + taue * other_old_phi[edgeii[1]]
                                if np.abs(self.level_set_alphatheta_enriched.phi[edgeii[0]] - ((1 - taue) * other_old_phi[edgeii[0]] + taue * other_old_phi[edgeii[1]])) > 1e-12:
                                    print('shift interpolate tau diff:', np.abs(cGrid.interpolate(other_old_phi, trii, tri, pe) - ((1 - taue) * other_old_phi[edgeii[0]] + taue * other_old_phi[edgeii[1]])))
                                    print('which phi, trii, edgeii ', which_phi, trii, edgeii)
                            elif which_phi == 2:
                                self.level_set_alphatheta_enriched.phi[edgeii[0]] = 0
                                self.level_set_gammaalpha_enriched.phi[edgeii[0]] = (1 - taue) * other_old_phi[edgeii[0]] + taue * other_old_phi[edgeii[1]]
                                if np.abs(self.level_set_gammaalpha_enriched.phi[edgeii[0]] - ((1 - taue) * other_old_phi[edgeii[0]] + taue * other_old_phi[edgeii[1]])) > 1e-12:
                                    print('shift interpolate tau diff:', np.abs(cGrid.interpolate(other_old_phi, trii, tri, pe) - ((1 - taue) * other_old_phi[edgeii[0]] + taue * other_old_phi[edgeii[1]])))
                                    print('which phi, trii, edgeii ', which_phi, trii, edgeii)
                        elif la.norm(pe - old_points[edgeii[0]]) <= la.norm(self.enriched_mesh.points[edgeii[0]] - old_points[edgeii[0]]):
                            self.enriched_mesh.points[edgeii[0]] = pe
                            self.background_mesh.Tau[edgeii[0]] = 0
                            self.background_mesh.Tau[edgeii[0], edgeii] = np.array([1-taue, taue])
                            self.background_mesh.Tau[edgeii[0], self.background_mesh.n] = edgeii[0]
                            if which_phi == 1:
                                self.level_set_gammaalpha_enriched.phi[edgeii[0]] = 0
                                self.level_set_alphatheta_enriched.phi[edgeii[0]] = (1 - taue) * other_old_phi[edgeii[0]] + taue * other_old_phi[edgeii[1]]
                                if np.abs(self.level_set_alphatheta_enriched.phi[edgeii[0]] - ((1 - taue) * other_old_phi[edgeii[0]] + taue * other_old_phi[edgeii[1]])) > 1e-12:
                                    print('shift interpolate tau diff:', np.abs(cGrid.interpolate(other_old_phi, trii, tri, pe) - ((1 - taue) * other_old_phi[edgeii[0]] + taue * other_old_phi[edgeii[1]])))
                                    print('which phi, trii, edgeii ', which_phi, trii, edgeii)
                            elif which_phi == 2:
                                self.level_set_alphatheta_enriched.phi[edgeii[0]] = 0
                                self.level_set_gammaalpha_enriched.phi[edgeii[0]] = (1 - taue) * other_old_phi[edgeii[0]] + taue * other_old_phi[edgeii[1]]
                                if np.abs(self.level_set_gammaalpha_enriched.phi[edgeii[0]] - ((1 - taue) * other_old_phi[edgeii[0]] + taue * other_old_phi[edgeii[1]])) > 1e-12:
                                    print('shift interpolate tau diff:', np.abs(cGrid.interpolate(other_old_phi, trii, tri, pe) - ((1 - taue) * other_old_phi[edgeii[0]] + taue * other_old_phi[edgeii[1]])))
                                    print('which phi, trii, edgeii ', which_phi, trii, edgeii)
                        if pii == 1:
                            eii = edgeii
                            p0 = pe
                            p0_index = edgeii[0]
                        elif pii == 2:
                            eii = edgeii
                            p1 = pe
                            p1_index = edgeii[0]
                        if which_phi == 2 and self.level_set_gammaalpha_enriched.phi[edgeii[0]] < 0:
                            self.has_point_been_shifted[edgeii[0]] = np.array([1, 3])
                        elif which_phi == 2:
                            self.has_point_been_shifted[edgeii[0]] = np.array([1, 2])
                        elif which_phi == 1 and self.level_set_alphatheta_enriched.phi[edgeii[0]] < 0:
                            self.has_point_been_shifted[edgeii[0]] = np.array([1, 1])
                        else:
                            self.has_point_been_shifted[edgeii[0]] = np.array([1, 11])
                    elif not(e1_delta):
                        if la.norm(self.enriched_mesh.points[edgeii[1]] - old_points[edgeii[1]]) == 0:
                            amount_shift = amount_shift + 1
                            self.enriched_mesh.points[edgeii[1]] = pe
                            self.background_mesh.Tau[edgeii[1], edgeii] = np.array([1-taue, taue])
                            self.background_mesh.Tau[edgeii[1], self.background_mesh.n] = edgeii[1]
                            if which_phi == 1:
                                self.level_set_gammaalpha_enriched.phi[edgeii[1]] = 0
                                self.level_set_alphatheta_enriched.phi[edgeii[1]] = (1 - taue) * other_old_phi[edgeii[0]] + taue * other_old_phi[edgeii[1]]
                                if np.abs(self.level_set_alphatheta_enriched.phi[edgeii[1]] - ((1 - taue) * other_old_phi[edgeii[0]] + taue * other_old_phi[edgeii[1]])) > 1e-12:
                                    print('shift interpolate tau diff:', np.abs(cGrid.interpolate(other_old_phi, trii, tri, pe) - ((1 - taue) * other_old_phi[edgeii[0]] + taue * other_old_phi[edgeii[1]])))
                                    print('which phi, trii, edgeii ', which_phi, trii, edgeii)
                            elif which_phi == 2:
                                self.level_set_alphatheta_enriched.phi[edgeii[1]] = 0
                                self.level_set_gammaalpha_enriched.phi[edgeii[1]] = (1 - taue) * other_old_phi[edgeii[0]] + taue * other_old_phi[edgeii[1]]
                                if np.abs(self.level_set_gammaalpha_enriched.phi[edgeii[1]] - ((1 - taue) * other_old_phi[edgeii[0]] + taue * other_old_phi[edgeii[1]])) > 1e-12:
                                    print('shift interpolate tau diff:', np.abs(cGrid.interpolate(other_old_phi, trii, tri, pe) - ((1 - taue) * other_old_phi[edgeii[0]] + taue * other_old_phi[edgeii[1]])))
                                    print('which phi, trii, edgeii ', which_phi, trii, edgeii)
                        elif la.norm(pe - old_points[edgeii[1]]) <= la.norm(self.enriched_mesh.points[edgeii[1]] - old_points[edgeii[1]]):
                            self.enriched_mesh.points[edgeii[1]] = pe
                            self.background_mesh.Tau[edgeii[1]] = 0
                            self.background_mesh.Tau[edgeii[1], edgeii] = np.array([1-taue, taue])
                            self.background_mesh.Tau[edgeii[1], self.background_mesh.n] = edgeii[1]
                            if which_phi == 1:
                                self.level_set_gammaalpha_enriched.phi[edgeii[1]] = 0
                                self.level_set_alphatheta_enriched.phi[edgeii[1]] = (1 - taue) * other_old_phi[edgeii[0]] + taue * other_old_phi[edgeii[1]]
                                if np.abs(self.level_set_alphatheta_enriched.phi[edgeii[1]] - ((1 - taue) * other_old_phi[edgeii[0]] + taue * other_old_phi[edgeii[1]])) > 1e-12:
                                    print('shift interpolate tau diff:', np.abs(cGrid.interpolate(other_old_phi, trii, tri, pe) - ((1 - taue) * other_old_phi[edgeii[0]] + taue * other_old_phi[edgeii[1]])))
                                    print('which phi, trii, edgeii ', which_phi, trii, edgeii)
                            elif which_phi == 2:
                                self.level_set_alphatheta_enriched.phi[edgeii[1]] = 0
                                self.level_set_gammaalpha_enriched.phi[edgeii[1]] = (1 - taue) * other_old_phi[edgeii[0]] + taue * other_old_phi[edgeii[1]]
                                if np.abs(self.level_set_gammaalpha_enriched.phi[edgeii[1]] - ((1 - taue) * other_old_phi[edgeii[0]] + taue * other_old_phi[edgeii[1]])) > 1e-12:
                                    print('shift interpolate tau diff:', np.abs(cGrid.interpolate(other_old_phi, trii, tri, pe) - ((1 - taue) * other_old_phi[edgeii[0]] + taue * other_old_phi[edgeii[1]])))
                                    print('which phi, trii, edgeii ', which_phi, trii, edgeii)
                        if pii == 1:
                            eii = edgeii
                            p0 = pe
                            p0_index = edgeii[1]
                        elif pii == 2:
                            eii = edgeii
                            p1 = pe
                            p1_index = edgeii[1]
                        if which_phi == 2 and self.level_set_gammaalpha_enriched.phi[edgeii[1]] < 0:
                            self.has_point_been_shifted[edgeii[1]] = np.array([1, 3])
                        elif which_phi == 2:
                            self.has_point_been_shifted[edgeii[1]] = np.array([1, 2])
                        elif which_phi == 1 and self.level_set_alphatheta_enriched.phi[edgeii[1]] < 0:
                            self.has_point_been_shifted[edgeii[1]] = np.array([1, 1])
                        else:
                            self.has_point_been_shifted[edgeii[1]] = np.array([1, 11])
                elif old_phi[edgeii[0]] * old_phi[edgeii[1]] == 0:
                    if which_phi == 1:
                        if old_phi[edgeii[0]] == 0 and self.has_point_been_shifted[edgeii[0],1]%4 != 0:
                            if self.level_set_alphatheta_enriched.phi[edgeii[0]] < 0:
                                self.has_point_been_shifted[edgeii[0]] = np.array([1, 1])
                            else:
                                self.has_point_been_shifted[edgeii[0]] = np.array([1, 11])
                        elif old_phi[edgeii[1]] == 0 and self.has_point_been_shifted[edgeii[1],1]%4 != 0:
                            if self.level_set_alphatheta_enriched.phi[edgeii[1]] < 0:
                                self.has_point_been_shifted[edgeii[1]] = np.array([1, 1])
                            else:
                                self.has_point_been_shifted[edgeii[1]] = np.array([1, 11])
                    elif which_phi == 2:
                        if old_phi[edgeii[0]] == 0 and self.has_point_been_shifted[edgeii[0],1]%4 != 0:
                            if self.level_set_gammaalpha_enriched.phi[edgeii[0]] < 0:
                                self.has_point_been_shifted[edgeii[0]] = np.array([1, 3])
                            else:
                                self.has_point_been_shifted[edgeii[0]] = np.array([1, 2])
                        elif old_phi[edgeii[1]] == 0 and self.has_point_been_shifted[edgeii[1],1]%4 != 0:
                            if self.level_set_gammaalpha_enriched.phi[edgeii[1]] < 0:
                                self.has_point_been_shifted[edgeii[1]] = np.array([1, 3])
                            else:
                                self.has_point_been_shifted[edgeii[1]] = np.array([1, 2])

            if amount_new > 0:
                if which_phi == 1:
                    if amount_new == 1: # and self.level_set_alphatheta_enriched.interpolate(trii, tri, p0_new) < 0:
                        interface_where_index_new_point = np.append(interface_where_index_new_point, which_tri[i])
                    elif amount_new == 2: # and self.level_set_alphatheta_enriched.interpolate(trii, tri, p0_new) < 0  and self.level_set_alphatheta_enriched.interpolate(trii, tri, p1_new) < 0:
                        interface_where_index_new_point = np.append(interface_where_index_new_point, which_tri[i])
                else:
                    interface_where_index_new_point = np.append(interface_where_index_new_point, which_tri[i])
        return interface_where_index_new_point
    
    
    
    ### Using the variance in angle we determine the quality of the triangle and pick the best one from those values. 
    ### Might want to use the skewness value as described in thesis.
    def calculate_var_angle_tri(tri, trii):
        a = tri[0] - tri[1]
        b = tri[0] - tri[2]
        angle0 = np.arccos((a[0]*b[0] + a[1]*b[1])/(la.norm(a)*la.norm(b)))
        if angle0 != angle0:
            angle0 = -1000
#            print('Invalid arccos, probably three points on one line. Is fixed by setting angle0 on -1000. Making variance very big, so never picking this option for triangles.')
        a = tri[1] - tri[0]
        b = tri[1] - tri[2]
        angle1 = np.arccos((a[0]*b[0] + a[1]*b[1])/(la.norm(a)*la.norm(b)))
        if angle1 != angle1:
            angle1 = -1000
#            print('Invalid arccos, probably three points on one line. Is fixed by setting angle1 on -1000. Making variance very big, so never picking this option for triangles.')

        angle2 = np.pi - angle0 - angle1
        return np.var(np.array([angle0,angle1,angle2]))
    

    ### Given 4 points, give the two triangles with least var
    def least_angle_trii(self, xa, xb, xc, xd):
        #option 1
        trii0_1 = np.hstack((xa, xb, xc))
        trii1_1 = np.hstack((xb, xc, xd))
        #option 2
        trii0_2 = np.hstack((xa, xb, xd))
        trii1_2 = np.hstack((xa, xc, xd))

        #check triangle properties
        tri0_1 = self.enriched_mesh.points[trii0_1]
        angle_0_var_1 = cGrid.calculate_var_angle_tri(tri0_1, trii0_1)
        tri1_1 = self.enriched_mesh.points[trii1_1]
        angle_1_var_1 = cGrid.calculate_var_angle_tri(tri1_1, trii1_1)
        angle_var_1 = np.mean([angle_0_var_1, angle_1_var_1])



        tri0_2 = self.enriched_mesh.points[trii0_2]
        angle_0_var_2 = cGrid.calculate_var_angle_tri(tri0_2, trii0_2)
        tri1_2 = self.enriched_mesh.points[trii1_2]
        angle_1_var_2 = cGrid.calculate_var_angle_tri(tri1_2, trii1_2)

        angle_var_2 = np.mean([angle_0_var_2, angle_1_var_2])

        if angle_var_1 < angle_var_2:
            return trii0_1, trii1_1
        else:
            return trii0_2, trii1_2


    ### Given 5 points, give the three triangles with least var
    def least_angle_trii_5p(self, xa, xb, xc, xd, xe):
        trii0_1, trii1_1 = cGrid.least_angle_trii(self, xa, xb, xc, xd)
        trii2_1 = np.array([xc, xd, xe])
        trii0_2, trii1_2 = cGrid.least_angle_trii(self, xa, xb, xc, xe)
        trii2_2 = np.array([xb, xd, xe])
        trii0_3, trii1_3 = cGrid.least_angle_trii(self, xa, xb, xe, xd)
        trii2_3 = np.array([xa, xc, xe])

        tri0_1 = self.enriched_mesh.points[trii0_1]
        tri1_1 = self.enriched_mesh.points[trii1_1]
        tri2_1 = self.enriched_mesh.points[trii2_1]
        angle_0_var_1 = cGrid.calculate_var_angle_tri(tri0_1, trii0_1)
        angle_1_var_1 = cGrid.calculate_var_angle_tri(tri1_1, trii1_1)
        angle_2_var_1 = cGrid.calculate_var_angle_tri(tri2_1, trii2_1)
        angle_var_1 = np.mean([angle_0_var_1, angle_1_var_1, angle_2_var_1])

        tri0_2 = self.enriched_mesh.points[trii0_2]
        tri1_2 = self.enriched_mesh.points[trii1_2]
        tri2_2 = self.enriched_mesh.points[trii2_2]
        angle_0_var_2 = cGrid.calculate_var_angle_tri(tri0_2, trii0_2)
        angle_1_var_2 = cGrid.calculate_var_angle_tri(tri1_2, trii1_2)
        angle_2_var_2 = cGrid.calculate_var_angle_tri(tri2_2, trii2_2)
        angle_var_2 = np.mean([angle_0_var_2, angle_1_var_2, angle_2_var_2])

        tri0_3 = self.enriched_mesh.points[trii0_3]
        tri1_3 = self.enriched_mesh.points[trii1_3]
        tri2_3 = self.enriched_mesh.points[trii2_3]
        angle_0_var_3 = cGrid.calculate_var_angle_tri(tri0_3, trii0_3)
        angle_1_var_3 = cGrid.calculate_var_angle_tri(tri1_3, trii1_3)
        angle_2_var_3 = cGrid.calculate_var_angle_tri(tri2_3, trii2_3)
        angle_var_3 = np.mean([angle_0_var_3, angle_1_var_3, angle_2_var_3])

        where_min = np.argmin([angle_var_1, angle_var_2, angle_var_3])
        if where_min == 0:
            return trii0_1, trii1_1, trii2_1
        elif where_min == 1:
            return trii0_2, trii1_2, trii2_2
        elif where_min == 2:
            return trii0_3, trii1_3, trii2_3


    ### Triple shift/bend/cut with triple points determined (specific_x3) beforehand
    def triple_shift_bend_cut_fixed_triple(self, copy_enr_tri_index, specific_tri, specific_x3):
        enr_points = self.enriched_mesh.points.copy()
        count = 0
        found = False
        while count != len(specific_tri) and not(found):
            i = specific_tri[count]
            trii = copy_enr_tri_index[i]
            tri = enr_points[trii]

            lambda_barycentric = la.solve( np.array([ [tri[0,0], tri[1,0], tri[2,0]],
                                                      [tri[0,1], tri[1,1], tri[2,1]],
                                                      [1       , 1       , 1       ] ]), np.array([ specific_x3[0], specific_x3[1], 1]))
            on_edge = False
            if any(np.abs(lambda_barycentric) < 1e-12) or any(np.abs(lambda_barycentric-1) < 1e-12):
                tri_b = self.background_mesh.points[trii]
                lambda_barycentric_background = la.solve( np.array([ [tri_b[0,0], tri_b[1,0], tri_b[2,0]],
                                                                     [tri_b[0,1], tri_b[1,1], tri_b[2,1]],
                                                                     [1       , 1       , 1       ] ]), np.array([ specific_x3[0], specific_x3[1], 1]))
                if all(lambda_barycentric_background <= 1) and all(lambda_barycentric_background >= 0):
                    on_edge = True
            if all(lambda_barycentric <= 1) and all(lambda_barycentric >= 0) or on_edge:
                found = True
                where_lambda_smaller_other_delta, = np.where(lambda_barycentric < self.delta) #diamond cut off delta
                #shift
                if where_lambda_smaller_other_delta.shape[0] == 2 or any(self.has_point_been_shifted[trii,1]%4 == 0):
                    if not(any(self.has_point_been_shifted[trii,1]%4 == 0)):
                        x_ga_i = trii[np.setdiff1d(np.arange(0,3),where_lambda_smaller_other_delta)][0]
                        print('shifted point xk ', x_ga_i, self.enriched_mesh.points[x_ga_i],'to triple x', specific_x3)
                        self.enriched_mesh.points[x_ga_i] = specific_x3
                        self.level_set_gammaalpha_enriched.phi[x_ga_i] = 0
                        self.level_set_alphatheta_enriched.phi[x_ga_i] = 0
                        self.has_point_been_shifted[x_ga_i] = np.array([1,8])
                        self.triple_points_index = np.hstack((self.triple_points_index, x_ga_i))
                        triple_Tau = np.zeros(self.background_mesh.n+1)
                        triple_Tau[trii] = lambda_barycentric
                        if self.background_mesh.Tau[trii[0], trii[0]] != 0:
                            other_points = self.background_mesh.Tau[trii[0]].nonzero()[1]
                            triple_Tau[trii[0]] = 0
                            triple_Tau[[other_points]] = triple_Tau[[other_points]] + lambda_barycentric[0] * self.background_mesh.Tau[trii[0], other_points].toarray()
                        if self.background_mesh.Tau[trii[1], trii[1]] != 0:
                            other_points = self.background_mesh.Tau[trii[1]].nonzero()[1]
                            triple_Tau[trii[1]] = 0
                            triple_Tau[[other_points]] = triple_Tau[[other_points]] + lambda_barycentric[1] * self.background_mesh.Tau[trii[1], other_points].toarray()
                        if self.background_mesh.Tau[trii[2], trii[2]] != 0:
                            other_points = self.background_mesh.Tau[trii[2]].nonzero()[1]
                            triple_Tau[trii[2]] = 0
                            triple_Tau[[other_points]] = triple_Tau[[other_points]] + lambda_barycentric[2] * self.background_mesh.Tau[trii[2], other_points].toarray()
                        triple_Tau[self.background_mesh.n] = x_ga_i
                        self.background_mesh.Tau[x_ga_i] = triple_Tau

                        if x_ga_i == self.background_mesh.i_ghost_fixed:
                            print('Shifted fixed point to triple, ga-ghost dissolved but not triples')
                            self.background_mesh.i_ghost_fixed = -1
                            self.background_mesh.i_ghost_fixed_shifted = True
                    else:
                        print('Already shifted point xk to triple x', specific_x3)
                        print('lambda', lambda_barycentric)
                #bend
                elif where_lambda_smaller_other_delta.shape[0] == 1:
                    triple_Tau0 = np.zeros(self.background_mesh.n+1)
                    triple_Tau1 = np.zeros(self.background_mesh.n+1)
                    triple_Tau2 = np.zeros(self.background_mesh.n+1)
                    triple_Tau0[trii[0]] = lambda_barycentric[0]
                    triple_Tau1[trii[1]] = lambda_barycentric[1]
                    triple_Tau2[trii[2]] = lambda_barycentric[2]
                    if self.background_mesh.Tau[trii[0], trii[0]] != 0:
                        other_points = self.background_mesh.Tau[trii[0]].nonzero()[1]
                        triple_Tau0[trii[0]] = 0
                        triple_Tau0[[other_points]] = lambda_barycentric[0] * self.background_mesh.Tau[trii[0], other_points].toarray()
                    if self.background_mesh.Tau[trii[1], trii[1]] != 0:
                        other_points = self.background_mesh.Tau[trii[1]].nonzero()[1]
                        triple_Tau1[trii[1]] = 0
                        triple_Tau1[[other_points]] = lambda_barycentric[1] * self.background_mesh.Tau[trii[1], other_points].toarray()
                    if self.background_mesh.Tau[trii[2], trii[2]] != 0:
                        other_points = self.background_mesh.Tau[trii[2]].nonzero()[1]
                        triple_Tau2[trii[2]] = 0
                        triple_Tau2[[other_points]] = lambda_barycentric[2] * self.background_mesh.Tau[trii[2], other_points].toarray()
                    triple_Tau = triple_Tau0 + triple_Tau1 + triple_Tau2
                    triple_Tau[self.background_mesh.n] = self.enriched_mesh.n
                    self.background_mesh.Tau = vstack((self.background_mesh.Tau, triple_Tau), format = 'lil')
                    print('triple bend', specific_x3)

                    x_ga_index           = self.enriched_mesh.n
                    self.enriched_mesh.n = self.enriched_mesh.n + 1
                    self.enriched_mesh.points = np.vstack((self.enriched_mesh.points, specific_x3))
                    self.enriched_mesh.n_tri = self.enriched_mesh.n_tri + 2
                    self.level_set_gammaalpha_enriched.phi = np.hstack((self.level_set_gammaalpha_enriched.phi, 0))
                    self.level_set_alphatheta_enriched.phi = np.hstack((self.level_set_alphatheta_enriched.phi, 0))

                    edge_bend = np.setdiff1d(np.arange(0,3), where_lambda_smaller_other_delta)
                    e_bend = np.sort(trii[edge_bend])
                    j = self.background_mesh.edge_to_index[e_bend[0], e_bend[1]]
                    index_not_bend = trii[where_lambda_smaller_other_delta]

                    trii0 = np.hstack((e_bend[0], index_not_bend, x_ga_index))
                    trii1 = np.hstack((e_bend[1], index_not_bend, x_ga_index))

                    self.enriched_mesh.triangles_points_index[i] = trii0
                    self.enriched_mesh.triangles_points_index = np.vstack((self.enriched_mesh.triangles_points_index, trii1))


                    other_tri_i = np.setdiff1d(self.background_mesh.edge_in_tri[j], i)[0]
                    other_trii = self.background_mesh.triangles_points_index[other_tri_i]
                    other_trii_new0, other_trii_new1 = cGrid.least_angle_trii(self, e_bend[0], np.setdiff1d(other_trii, e_bend)[0], x_ga_index, e_bend[1])

                    self.enriched_mesh.triangles_points_index[other_tri_i] = other_trii_new0
                    self.enriched_mesh.triangles_points_index = np.vstack((self.enriched_mesh.triangles_points_index, other_trii_new1))

                    self.triple_points_index = np.hstack((self.triple_points_index, x_ga_index))
                    self.has_point_been_shifted = np.vstack((self.has_point_been_shifted, np.array([1, 12])))
                #cut
                elif where_lambda_smaller_other_delta.shape[0] == 0:
                    triple_Tau0 = np.zeros(self.background_mesh.n+1)
                    triple_Tau1 = np.zeros(self.background_mesh.n+1)
                    triple_Tau2 = np.zeros(self.background_mesh.n+1)
                    triple_Tau0[trii[0]] = lambda_barycentric[0]
                    triple_Tau1[trii[1]] = lambda_barycentric[1]
                    triple_Tau2[trii[2]] = lambda_barycentric[2]
                    if self.background_mesh.Tau[trii[0], trii[0]] != 0:
                        other_points = self.background_mesh.Tau[trii[0]].nonzero()[1]
                        triple_Tau0[trii[0]] = 0
                        triple_Tau0[[other_points]] = lambda_barycentric[0] * self.background_mesh.Tau[trii[0], other_points].toarray()
                    if self.background_mesh.Tau[trii[1], trii[1]] != 0:
                        other_points = self.background_mesh.Tau[trii[1]].nonzero()[1]
                        triple_Tau1[trii[1]] = 0
                        triple_Tau1[[other_points]] = lambda_barycentric[1] * self.background_mesh.Tau[trii[1], other_points].toarray()
                    if self.background_mesh.Tau[trii[2], trii[2]] != 0:
                        other_points = self.background_mesh.Tau[trii[2]].nonzero()[1]
                        triple_Tau2[trii[2]] = 0
                        triple_Tau2[[other_points]] = lambda_barycentric[2] * self.background_mesh.Tau[trii[2], other_points].toarray()
                    triple_Tau = triple_Tau0 + triple_Tau1 + triple_Tau2
                    triple_Tau[self.background_mesh.n] = self.enriched_mesh.n
                    self.background_mesh.Tau = vstack((self.background_mesh.Tau, triple_Tau), format = 'lil')
                    print('triple cut', specific_x3)
                    x_ga_index           = self.enriched_mesh.n
                    self.enriched_mesh.n = self.enriched_mesh.n + 1

                    self.enriched_mesh.points = np.vstack((self.enriched_mesh.points, specific_x3))
                    self.enriched_mesh.n_tri = self.enriched_mesh.n_tri + 2
                    self.level_set_gammaalpha_enriched.phi = np.hstack((self.level_set_gammaalpha_enriched.phi, 0))
                    self.level_set_alphatheta_enriched.phi = np.hstack((self.level_set_alphatheta_enriched.phi, 0))

                    trii0 = np.hstack((trii[0], trii[1], x_ga_index))
                    trii1 = np.hstack((trii[0], trii[2], x_ga_index))
                    trii2 = np.hstack((trii[1], trii[2], x_ga_index))

                    self.enriched_mesh.triangles_points_index[i] = trii0
                    self.enriched_mesh.triangles_points_index = np.vstack((self.enriched_mesh.triangles_points_index, trii1, trii2))

                    self.triple_points_index = np.hstack((self.triple_points_index, x_ga_index))
                    self.has_point_been_shifted = np.vstack((self.has_point_been_shifted, np.array([1, 4])))
                #For high values of delta always cut
                else:
                    triple_Tau0 = np.zeros(self.background_mesh.n+1)
                    triple_Tau1 = np.zeros(self.background_mesh.n+1)
                    triple_Tau2 = np.zeros(self.background_mesh.n+1)
                    triple_Tau0[trii[0]] = lambda_barycentric[0]
                    triple_Tau1[trii[1]] = lambda_barycentric[1]
                    triple_Tau2[trii[2]] = lambda_barycentric[2]
                    if self.background_mesh.Tau[trii[0], trii[0]] != 0:
                        other_points = self.background_mesh.Tau[trii[0]].nonzero()[1]
                        triple_Tau0[trii[0]] = 0
                        triple_Tau0[[other_points]] = lambda_barycentric[0] * self.background_mesh.Tau[trii[0], other_points].toarray()
                    if self.background_mesh.Tau[trii[1], trii[1]] != 0:
                        other_points = self.background_mesh.Tau[trii[1]].nonzero()[1]
                        triple_Tau1[trii[1]] = 0
                        triple_Tau1[[other_points]] = lambda_barycentric[1] * self.background_mesh.Tau[trii[1], other_points].toarray()
                    if self.background_mesh.Tau[trii[2], trii[2]] != 0:
                        other_points = self.background_mesh.Tau[trii[2]].nonzero()[1]
                        triple_Tau2[trii[2]] = 0
                        triple_Tau2[[other_points]] = lambda_barycentric[2] * self.background_mesh.Tau[trii[2], other_points].toarray()
                    triple_Tau = triple_Tau0 + triple_Tau1 + triple_Tau2
                    triple_Tau[self.background_mesh.n] = self.enriched_mesh.n
                    self.background_mesh.Tau = vstack((self.background_mesh.Tau, triple_Tau), format = 'lil')
                    print('triple cut weird deltas', specific_x3)
                    x_ga_index           = self.enriched_mesh.n
                    self.enriched_mesh.n = self.enriched_mesh.n + 1

                    self.enriched_mesh.points = np.vstack((self.enriched_mesh.points, specific_x3))
                    self.enriched_mesh.n_tri = self.enriched_mesh.n_tri + 2
                    self.level_set_gammaalpha_enriched.phi = np.hstack((self.level_set_gammaalpha_enriched.phi, 0))
                    self.level_set_alphatheta_enriched.phi = np.hstack((self.level_set_alphatheta_enriched.phi, 0))

                    trii0 = np.hstack((trii[0], trii[1], x_ga_index))
                    trii1 = np.hstack((trii[0], trii[2], x_ga_index))
                    trii2 = np.hstack((trii[1], trii[2], x_ga_index))

                    self.enriched_mesh.triangles_points_index[i] = trii0
                    self.enriched_mesh.triangles_points_index = np.vstack((self.enriched_mesh.triangles_points_index, trii1, trii2))

                    self.triple_points_index = np.hstack((self.triple_points_index, x_ga_index))
                    self.has_point_been_shifted = np.vstack((self.has_point_been_shifted, np.array([1, 4])))
            count = count + 1






    ### Triple shift/bend/cut old version where we added the other interface points as well as the triple points. 
    ### A lot more code because of all the different options and less flexible I think.
    def triple_shift_bend_cut(self, copy_enr_tri_index):
        phi_ga = self.level_set_gammaalpha_enriched.phi.copy()
        phi_at = self.level_set_alphatheta_enriched.phi.copy()
        interface_where_index_new_point = np.zeros((0),dtype=np.int)
        interface_ga_where_index = np.zeros((0),dtype=np.int)
        interface_at_where_index = np.zeros((0),dtype=np.int)

        for i in range(0,self.enriched_mesh.n_tri):
            trii = copy_enr_tri_index[i]
            tri = self.enriched_mesh.points[trii]

            ga_at = 0
            ga = 0
            at = 0
            for edgei in np.array([[0,1],[0,2],[1,2]]):
                edgeii = np.sort(trii[edgei])
                edge = tri[edgei[np.argsort(trii[edgei])]]
                j = self.enriched_mesh.edge_to_index[edgeii[0], edgeii[1]]
                ga_tri = phi_ga[edgeii[0]] * phi_ga[edgeii[1]] < 0
                at_tri = phi_at[edgeii[0]] * phi_at[edgeii[1]] < 0
                if ga_tri:
                    taue_ga = -phi_ga[edgeii[0]]/(phi_ga[edgeii[1]] - phi_ga[edgeii[0]])
                    pe_ga = (1-taue_ga) * edge[0] + taue_ga * edge[1]
                if at_tri:
                    taue_at = -phi_at[edgeii[0]]/(phi_at[edgeii[1]] - phi_at[edgeii[0]])
                    pe_at = (1-taue_at) * edge[0] + taue_at * edge[1]
                if ga_tri and at_tri:
                    ga_at = ga_at + 1
                    if ga_at == 1:
                        p02_ga = pe_ga
                        p02_at = pe_at
                        taue02_ga = taue_ga
                        taue02_at = taue_at
                        j02 = j
                        e02 = edgeii
                    elif ga_at == 2:
                        p12_ga = pe_ga
                        p12_at = pe_at
                        taue12_ga = taue_ga
                        taue12_at = taue_at
                        j12 = j
                        e12 = edgeii
                    else:
                        print('3 cross triangle? ',ga_at)
                elif ga_tri or at_tri:
                    if ga_tri:
                        ga = ga + 1
                        if ga == 1:
                            p01_ga = pe_ga
                            taue01_ga = taue_ga
                            j01_ga = j
                            e01_ga = edgeii
                        elif ga == 2:
                            p11_ga = pe_ga
                            taue11_ga = taue_ga
                            j11_ga = j
                            e11_ga = edgeii
                    if at_tri:
                        at = at + 1
                        if at == 1:
                            p01_at = pe_at
                            taue01_at = taue_at
                            j01_at = j
                            e01_at = edgeii
                        elif at == 2:
                            p11_at = pe_at
                            taue11_at = taue_at
                            j11_at = j
                            e11_at = edgeii
                j=j+1
            #If triangle has a point where phi < 0 and phi > 0, the interface has to be crossing this triangle
            ga_intersect = any(phi_ga[trii] > 0) and any(phi_ga[trii] < 0)
            at_intersect = any(phi_at[trii] > 0) and any(phi_at[trii] < 0)
            #Also when two points of a triangle have phi = 0, the interface is crossing this triangle through this edge
            where_ga, = np.where(phi_ga[trii] == 0)
            where_at, = np.where(phi_at[trii] == 0)

            if where_ga.shape[0] == 2 and where_at.shape[0] != 2:
                edge_ga = np.sort(trii[where_ga])
                j_ga_edge = self.background_mesh.edge_to_index[edge_ga[0], edge_ga[1]]
                other_tri_i = np.setdiff1d(self.background_mesh.edge_in_tri[j_ga_edge], i)[0]
#                print('shape ga == 2 other_tri_i trii edge ga j_edge',other_tri_i, self.background_mesh.triangles_points_index[other_tri_i], edge_ga, j_ga_edge)
                if self.has_point_been_shifted[np.setdiff1d(self.background_mesh.triangles_points_index[other_tri_i], edge_ga), 1]%4 != 0:
                    ga_intersect = True
            if where_at.shape[0] == 2 and where_ga.shape[0] != 2:
                edge_at = np.sort(trii[where_at])
                j_at_edge = self.background_mesh.edge_to_index[edge_at[0], edge_at[1]]
                other_tri_i = np.setdiff1d(self.background_mesh.edge_in_tri[j_at_edge], i)[0]
#                print('shape at == 2 other_tri_i trii edge at j_edge',other_tri_i, self.background_mesh.triangles_points_index[other_tri_i], edge_at, j_at_edge)
                if self.has_point_been_shifted[np.setdiff1d(self.background_mesh.triangles_points_index[other_tri_i], edge_at)[0], 1]%4 != 0:
                    at_intersect = True


            if ga_intersect and at_intersect:
                #Both interfaces cut one similar edge
                if ga_at == 1:
                    #Both interfaces cut other two edges
                    if ga + at == 2:
                        pass
                    #One interface cut edge, other interface goes through corner.
                    elif ga + at == 1:
                        if ga == 0:
                            where_p01_ga_index, = np.where(phi_ga[trii] == 0)
                            p01_ga_index = trii[where_p01_ga_index[0]]
                            p01_ga = tri[where_p01_ga_index][0]
                        elif at == 0:
                            where_p01_at_index, = np.where(phi_at[trii] == 0)
                            p01_at_index = trii[where_p01_at_index][0]
                            p01_at = tri[where_p01_at_index][0]
                    #Both interfaces go through a corner
                    elif ga + at == 0:
                        where_p01_ga_index, = np.where(phi_ga[trii] == 0)
                        p01_ga_index = trii[where_p01_ga_index[0]]
                        p01_ga = tri[where_p01_ga_index][0]
                        where_p01_at_index, = np.where(phi_at[trii] == 0)
                        p01_at_index = trii[where_p01_at_index][0]
                        p01_at = tri[where_p01_at_index][0]
                    X = np.array( [[p02_ga[0] - p01_ga[0], p01_at[0] - p02_at[0]],
                                   [p02_ga[1] - p01_ga[1], p01_at[1] - p02_at[1]]] )
                    if la.det(X) != 0:
                         t = la.solve( X, np.array( [p01_at[0] - p01_ga[0], p01_at[1] - p01_ga[1]] ) )
                    else:
#                        print('interfaces parallel, X singular')  #(parallel lines)
                        t = np.ones(2) * np.inf
                #Both interfaces cut the same two edges
                elif ga_at == 2:
                    X =np.array( [[p02_ga[0] - p12_ga[0], p12_at[0] - p02_at[0]],
                                  [p02_ga[1] - p12_ga[1], p12_at[1] - p02_at[1]]] )
                    if la.det(X) != 0:
                         t = la.solve( X, np.array( [ p12_at[0] - p12_ga[0], p12_at[1] - p12_ga[1] ] ) )
                    else:
#                        print('interfaces parallel, X singular')
                        t = np.ones(2) * np.inf
                #One interface goes through a corner and both interfaces cut different edges
                elif ga_at == 0 and ga + at == 3:
                    if ga == 1:
                        where_p11_ga_index, = np.where(phi_ga[trii] == 0)
                        p11_ga_index = trii[where_p11_ga_index][0]
                        p11_ga = tri[where_p11_ga_index][0]
                    elif at == 1:
                        where_p11_at_index, = np.where(phi_at[trii] == 0)
                        p11_at_index = trii[where_p11_at_index][0]
                        p11_at = tri[where_p11_at_index][0]
                    X = np.array( [[p01_ga[0] - p11_ga[0], p11_at[0] - p01_at[0]],
                                             [p01_ga[1] - p11_ga[1], p11_at[1] - p01_at[1]]] )
                    if la.det(X) != 0:
                         t = la.solve( X, np.array(  [p11_at[0] - p11_ga[0], p11_at[1] - p11_ga[1] ] ) )
                    else:
#                            print('interfaces parallel, X singular')
                        t = np.ones(2) * np.inf
                #Both interfaces go through a corner and both interfaces cut different edges
                elif ga_at == 0:
                    #Both cut ones and go through corner ones
                    if ga == 1 and at == 1:
                        where_p11_ga_index, = np.where(phi_ga[trii] == 0)
                        p11_ga_index = trii[where_p11_ga_index][0]
                        p11_ga = tri[where_p11_ga_index][0]
                        where_p11_at_index, = np.where(phi_at[trii] == 0)
                        p11_at_index = trii[where_p11_at_index][0]
                        p11_at = tri[where_p11_at_index][0]
                    #gamma/alpha goes through two corners and theta goes through two edges
                    elif ga == 0 and at == 2:
                        where_p01_ga_index, = np.where(phi_ga[trii] == 0)
                        p01_ga_index = trii[where_p01_ga_index][0]
                        p11_ga_index = trii[where_p01_ga_index][1]
                        p01_ga = tri[where_p01_ga_index][0]
                        p11_ga = tri[where_p01_ga_index][1]
                    #theta goes through two corners and gamma/alpha goes through two edges
                    elif at == 0 and ga == 2:
                        where_p01_at_index, = np.where(phi_at[trii] == 0)
                        p01_at_index = trii[where_p01_at_index][0]
                        p11_at_index = trii[where_p01_at_index][1]
                        p01_at = tri[where_p01_at_index][0]
                        p11_at = tri[where_p01_at_index][1]
                    elif ga == 1 and at == 0:
                        where_p01_at_index, = np.where(phi_at[trii] == 0)
                        p01_at_index = trii[where_p01_at_index][0]
                        p11_at_index = trii[where_p01_at_index][1]
                        p01_at = tri[where_p01_at_index][0]
                        p11_at = tri[where_p01_at_index][1]
                        where_p01_ga_index, = np.where(phi_ga[trii] == 0)
                        p11_ga_index = trii[where_p01_ga_index][0]
                        p11_ga = tri[where_p01_ga_index][0]
                    elif ga == 0 and at == 1:
                        where_p01_at_index, = np.where(phi_at[trii] == 0)
                        p11_at_index = trii[where_p01_at_index][0]
                        p11_at = tri[where_p01_at_index][0]
                        where_p01_ga_index, = np.where(phi_ga[trii] == 0)
                        p01_ga_index = trii[where_p01_ga_index][0]
                        p11_ga_index = trii[where_p01_ga_index][1]
                        p01_ga = tri[where_p01_ga_index][0]
                        p11_ga = tri[where_p01_ga_index][1]
                    X = np.array( [[p01_ga[0] - p11_ga[0], p11_at[0] - p01_at[0]],
                                   [p01_ga[1] - p11_ga[1], p11_at[1] - p01_at[1]]] )
                    if la.det(X) != 0:
                        t = la.solve( X, np.array(  [p11_at[0] - p11_ga[0], p11_at[1] - p11_ga[1] ] ) )
                    else:
#                            print('interfaces parallel, X singular')
                        t = np.ones(2) * np.inf
                else:
                    print('something weird with double cross triangles')


                if all(t >= 0) and all(t <= 1) and not(all(np.sort(t) == np.array([0,1]))) and not(all(t == np.zeros(2))) and not(all(t == np.ones(2))):
                    not_triple = False
                    self.trii_triple = np.hstack((self.trii_triple, i))
                    if ga_at == 1:
                        x_ga = (1-t[0]) * p01_ga + t[0] * p02_ga
                        x_at = (1-t[1]) * p01_at + t[1] * p02_at
                    elif ga_at == 2:
                        x_ga = (1-t[0]) * p12_ga + t[0] * p02_ga
                        x_at = (1-t[1]) * p12_at + t[1] * p02_at
                    elif ga_at == 0:
                        x_ga = (1-t[0]) * p11_ga + t[0] * p01_ga
                        x_at = (1-t[1]) * p11_at + t[1] * p01_at
                    if la.norm(x_ga - x_at) > 1e-14:
                        print('triple point not accurate, x_ga ', x_ga, 'x_at ', x_at)
                    #In stead of looking at each corner, calculate barycentric lambda, which is same as taue_xk
                    lambda_barycentric = la.solve( np.array([ [tri[0,0], tri[1,0], tri[2,0]],
                                                              [tri[0,1], tri[1,1], tri[2,1]],
                                                              [1       , 1       , 1       ] ]), np.array([ x_ga[0], x_ga[1], 1]))

                    where_lambda_big, = np.where(1-lambda_barycentric < self.delta) #triangle cutoff at delta
                    where_lambda_smaller_other_delta, = np.where(lambda_barycentric < self.delta) #diamond cut off delta
                    shape_where_lambda_small_is_1 = False
                    if where_lambda_big.shape[0] > 1:
                        print('error in barycentric coordinates, two lambda < delta (or delta close to 1/2?)')
                    elif where_lambda_big.shape[0] == 1:
                        shape_where_lambda_small_is_1 = True
#                        if where_lambda_smaller_other_delta.shape[0] > 0:
#                            print('has been shifted shape boolean array',where_lambda_smaller_other_delta.shape[0],where_lambda_smaller_other_delta, self.has_point_been_shifted[trii[np.setdiff1d(np.arange(0,3),where_lambda_smaller_other_delta[0])]] == np.array([1,4]))
                    #if a lambda < 1 - delta, shift point to that corner, but not interface points. check this with has_been_shifted.
#                        if where_lambda_big.shape[0] == 1 and not(self.has_point_been_shifted[trii[where_lambda_big[0]],0] == 1):
                    if where_lambda_smaller_other_delta.shape[0] == 2 or any(self.has_point_been_shifted[trii,1]%4 == 0):
                        if not(any(self.has_point_been_shifted[trii,1]%4 == 0)):
                            x_ga_i = trii[np.setdiff1d(np.arange(0,3),where_lambda_smaller_other_delta)][0]
                            print('shifted2 point xk ', x_ga_i, self.enriched_mesh.points[x_ga_i],'to triple x', x_ga)
                            self.enriched_mesh.points[x_ga_i] = x_ga
                            self.level_set_gammaalpha_enriched.phi[x_ga_i] = 0
                            self.level_set_alphatheta_enriched.phi[x_ga_i] = 0
                            self.has_point_been_shifted[x_ga_i] = np.array([1,8])
                            self.triple_points_index = np.hstack((self.triple_points_index, x_ga_i))
                            triple_Tau = np.zeros(self.background_mesh.n+1)
                            triple_Tau[trii] = lambda_barycentric
                            if self.background_mesh.Tau[trii[0], trii[0]] != 0:
                                other_points = self.background_mesh.Tau[trii[0]].nonzero()[1]
                                triple_Tau[trii[0]] = 0
                                triple_Tau[[other_points]] = triple_Tau[[other_points]] + lambda_barycentric[0] * self.background_mesh.Tau[trii[0], other_points].toarray()
                            if self.background_mesh.Tau[trii[1], trii[1]] != 0:
                                other_points = self.background_mesh.Tau[trii[1]].nonzero()[1]
                                triple_Tau[trii[1]] = 0
                                triple_Tau[[other_points]] = triple_Tau[[other_points]] + lambda_barycentric[1] * self.background_mesh.Tau[trii[1], other_points].toarray()
                            if self.background_mesh.Tau[trii[2], trii[2]] != 0:
                                other_points = self.background_mesh.Tau[trii[2]].nonzero()[1]
                                triple_Tau[trii[2]] = 0
                                triple_Tau[[other_points]] = triple_Tau[[other_points]] + lambda_barycentric[2] * self.background_mesh.Tau[trii[2], other_points].toarray()
                            triple_Tau[self.background_mesh.n] = x_ga_i
                            self.background_mesh.Tau[x_ga_i] = triple_Tau
                        else:
                            print('Already shifted point xk to triple x', x_ga)

                    #if a lambda < delta and no shift as above, triple point is close to an edge. cut and shift (bend) this edge
#                        elif any(lambda_barycentric < self.delta) or shape_where_lambda_small_is_1 and self.has_point_been_shifted[trii[where_lambda_big][0],0] == 1 and not(self.has_point_been_shifted[trii[where_lambda_big][0],1] == 4):
                    elif where_lambda_smaller_other_delta.shape[0] == 1:
                        triple_Tau0 = np.zeros(self.background_mesh.n+1)
                        triple_Tau1 = np.zeros(self.background_mesh.n+1)
                        triple_Tau2 = np.zeros(self.background_mesh.n+1)
                        triple_Tau0[trii[0]] = lambda_barycentric[0]
                        triple_Tau1[trii[1]] = lambda_barycentric[1]
                        triple_Tau2[trii[2]] = lambda_barycentric[2]
                        if self.background_mesh.Tau[trii[0], trii[0]] != 0:
                            other_points = self.background_mesh.Tau[trii[0]].nonzero()[1]
                            triple_Tau0[trii[0]] = 0
                            triple_Tau0[[other_points]] = lambda_barycentric[0] * self.background_mesh.Tau[trii[0], other_points].toarray()
                        if self.background_mesh.Tau[trii[1], trii[1]] != 0:
                            other_points = self.background_mesh.Tau[trii[1]].nonzero()[1]
                            triple_Tau1[trii[1]] = 0
                            triple_Tau1[[other_points]] = lambda_barycentric[1] * self.background_mesh.Tau[trii[1], other_points].toarray()
                        if self.background_mesh.Tau[trii[2], trii[2]] != 0:
                            other_points = self.background_mesh.Tau[trii[2]].nonzero()[1]
                            triple_Tau2[trii[2]] = 0
                            triple_Tau2[[other_points]] = lambda_barycentric[2] * self.background_mesh.Tau[trii[2], other_points].toarray()
                        triple_Tau = triple_Tau0 + triple_Tau1 + triple_Tau2
                        triple_Tau[self.background_mesh.n] = self.enriched_mesh.n
                        self.background_mesh.Tau = vstack((self.background_mesh.Tau, triple_Tau), format = 'lil')
                        print('bend ga_at, ga, at', ga_at, ga, at, x_ga)
                        print('1-lambda_barycentric ', 1-lambda_barycentric, 'trii ', trii)
                        if ga_at == 1:
                            if ga == 1 and at == 1: #bend 111, can only bend over e02
                                x_ga_index   = self.enriched_mesh.n + 0
                                p01_ga_index = self.enriched_mesh.n + 1
                                p01_at_index = self.enriched_mesh.n + 2

                                self.enriched_mesh.points = np.vstack((self.enriched_mesh.points, x_ga, p01_ga, p01_at))
                                phi_at_pe = self.level_set_alphatheta_enriched.interpolate(trii, tri, p01_ga)
                                if phi_at_pe < 0:
                                    self.has_point_been_shifted = np.vstack((self.has_point_been_shifted, [1, 12], [1, 1]))
                                else:
                                    self.has_point_been_shifted = np.vstack((self.has_point_been_shifted, [1, 12], [1, 11]))
                                phi_ga_pe = self.level_set_gammaalpha_enriched.interpolate(trii, tri, p01_at)
                                if phi_ga_pe < 0:
                                    self.has_point_been_shifted = np.vstack((self.has_point_been_shifted, [1, 3]))
                                else:
                                    self.has_point_been_shifted = np.vstack((self.has_point_been_shifted, [1, 2]))
                                self.level_set_gammaalpha_enriched.phi = np.hstack((self.level_set_gammaalpha_enriched.phi, 0, 0, phi_ga_pe))
                                self.level_set_alphatheta_enriched.phi = np.hstack((self.level_set_alphatheta_enriched.phi, 0, phi_at_pe, 0))

                                cut_Tau = np.zeros(self.background_mesh.n+1)
                                cut_Tau[[e01_ga]] = np.array([1-taue01_ga, taue01_ga])
                                if self.background_mesh.Tau[e01_ga[0], e01_ga[0]] != 0:
                                    other_points = self.background_mesh.Tau[e01_ga[0]].nonzero()[1]
                                    cut_Tau[e01_ga[0]] = 0
                                    cut_Tau[[other_points]] = cut_Tau[[other_points]] + (1-taue01_ga) * self.background_mesh.Tau[e01_ga[0], other_points].toarray()
                                if self.background_mesh.Tau[e01_ga[1], e01_ga[1]] != 0:
                                    other_points = self.background_mesh.Tau[e01_ga[1]].nonzero()[1]
                                    cut_Tau[e01_ga[1]] = 0
                                    cut_Tau[[other_points]] = cut_Tau[[other_points]] + taue01_ga * self.background_mesh.Tau[e01_ga[1], other_points].toarray()
                                cut_Tau[self.background_mesh.n] = p01_ga_index
                                self.background_mesh.Tau = vstack((self.background_mesh.Tau, cut_Tau), format = 'lil')

                                trii0 = np.hstack((np.intersect1d(e02, e01_ga)[0], p01_ga_index, x_ga_index))
                                trii1 = np.hstack((np.intersect1d(e02, e01_at)[0], p01_at_index, x_ga_index))
                                trii2, trii3 = cGrid.least_angle_trii(self, np.intersect1d(e01_ga, e01_at), p01_ga_index, p01_at_index, x_ga_index)

                                self.enriched_mesh.triangles_points_index[i] = trii0
                                self.enriched_mesh.triangles_points_index = np.vstack((self.enriched_mesh.triangles_points_index, trii1, trii2, trii3))

                                other_tri_i = np.setdiff1d(self.background_mesh.edge_in_tri[j02], i)[0]
                                other_trii = self.background_mesh.triangles_points_index[other_tri_i]
                                other_trii_new0, other_trii_new1 = cGrid.least_angle_trii(self, e02[0], np.setdiff1d(other_trii, e02)[0], x_ga_index, e02[1])

                                self.enriched_mesh.triangles_points_index[other_tri_i] = other_trii_new0
                                self.enriched_mesh.triangles_points_index = np.vstack((self.enriched_mesh.triangles_points_index, other_trii_new1))

                                self.has_edge_been_handled[j01_ga] = p01_ga_index
                                self.has_edge_been_handled[j01_at] = p01_at_index

                                self.enriched_mesh.n_tri = self.enriched_mesh.n_tri + 4
                                self.enriched_mesh.n = self.enriched_mesh.n + 3
                            elif ga == 0: #then at must be 1 bend 101
                                x_ga_index = self.enriched_mesh.n + 0
                                self.enriched_mesh.points = np.vstack((self.enriched_mesh.points, x_ga))
                                self.has_point_been_shifted = np.vstack((self.has_point_been_shifted, [1, 12]))
                                self.level_set_gammaalpha_enriched.phi = np.hstack((self.level_set_gammaalpha_enriched.phi, 0))
                                self.level_set_alphatheta_enriched.phi = np.hstack((self.level_set_alphatheta_enriched.phi, 0))
                                if lambda_barycentric[np.where(trii == np.setdiff1d(e02, e01_at)[0])][0] < self.delta: #then bend to e01_at
                                    print('bend on e01_at edge')
                                    p02_at_index = self.enriched_mesh.n + 1
                                    self.enriched_mesh.points = np.vstack((self.enriched_mesh.points, p02_at))

                                    phi_ga_pe = self.level_set_gammaalpha_enriched.interpolate(trii, tri, p02_at)
                                    if phi_ga_pe < 0:
                                        self.has_point_been_shifted = np.vstack((self.has_point_been_shifted, [1, 3]))
                                    else:
                                        self.has_point_been_shifted = np.vstack((self.has_point_been_shifted, [1, 2]))
                                    self.level_set_gammaalpha_enriched.phi = np.hstack((self.level_set_gammaalpha_enriched.phi, phi_ga_pe))
                                    self.level_set_alphatheta_enriched.phi = np.hstack((self.level_set_alphatheta_enriched.phi, 0))

                                    cut_Tau = np.zeros(self.background_mesh.n+1)
                                    cut_Tau[[e02]] = np.array([1-taue02_at, taue02_at])
                                    if self.background_mesh.Tau[e02[0], e02[0]] != 0:
                                        other_points = self.background_mesh.Tau[e02[0]].nonzero()[1]
                                        cut_Tau[e02[0]] = 0
                                        cut_Tau[[other_points]] = cut_Tau[[other_points]] + (1-taue02_at) * self.background_mesh.Tau[e02[0], other_points].toarray()
                                    if self.background_mesh.Tau[e02[1], e02[1]] != 0:
                                        other_points = self.background_mesh.Tau[e02[1]].nonzero()[1]
                                        cut_Tau[e02[1]] = 0
                                        cut_Tau[[other_points]] = cut_Tau[[other_points]] + taue02_at * self.background_mesh.Tau[e02[1], other_points].toarray()
                                    cut_Tau[self.background_mesh.n] = p02_at_index
                                    self.background_mesh.Tau = vstack((self.background_mesh.Tau, cut_Tau), format = 'lil')

                                    p02_ga_index = self.enriched_mesh.n + 2

                                    self.enriched_mesh.points = np.vstack((self.enriched_mesh.points, p02_ga))
                                    if self.has_point_been_shifted[p01_ga_index, 1] == 1:
                                        self.has_point_been_shifted = np.vstack((self.has_point_been_shifted, [1, 11]))
                                    elif self.has_point_been_shifted[p01_ga_index, 1] == 11:
                                        self.has_point_been_shifted = np.vstack((self.has_point_been_shifted, [1, 1]))
                                    else:
                                        print('p01_ga_index not ga?')
                                    self.level_set_gammaalpha_enriched.phi = np.hstack((self.level_set_gammaalpha_enriched.phi, 0))
                                    self.level_set_alphatheta_enriched.phi = np.hstack((self.level_set_alphatheta_enriched.phi,
                                                                                        self.level_set_alphatheta_enriched.interpolate(trii, tri, p02_ga)))

                                    cut_Tau = np.zeros(self.background_mesh.n+1)
                                    cut_Tau[[e02]] = np.array([1-taue02_ga, taue02_ga])
                                    if self.background_mesh.Tau[e02[0], e02[0]] != 0:
                                        other_points = self.background_mesh.Tau[e02[0]].nonzero()[1]
                                        cut_Tau[e02[0]] = 0
                                        cut_Tau[[other_points]] = cut_Tau[[other_points]] + (1-taue02_ga) * self.background_mesh.Tau[e02[0], other_points].toarray()
                                    if self.background_mesh.Tau[e02[1], e02[1]] != 0:
                                        other_points = self.background_mesh.Tau[e02[1]].nonzero()[1]
                                        cut_Tau[e02[1]] = 0
                                        cut_Tau[[other_points]] = cut_Tau[[other_points]] + taue02_ga * self.background_mesh.Tau[e02[1], other_points].toarray()
                                    cut_Tau[self.background_mesh.n] = p02_ga_index
                                    self.background_mesh.Tau = vstack((self.background_mesh.Tau, cut_Tau), format = 'lil')

                                    trii0 = np.hstack((np.intersect1d(e02, e01_at)[0], p02_ga_index, x_ga_index))
                                    trii1 = np.hstack((p02_ga_index, p02_at_index, x_ga_index))
                                    trii2, trii3 = cGrid.least_angle_trii(self, np.setdiff1d(e02, e01_at)[0], p01_ga_index, p02_at_index, x_ga_index)

                                    self.enriched_mesh.triangles_points_index[i] = trii3
                                    self.enriched_mesh.triangles_points_index = np.vstack((self.enriched_mesh.triangles_points_index, trii0, trii1, trii2))

                                    other_tri_i = np.setdiff1d(self.background_mesh.edge_in_tri[j01_at], i)[0]
                                    other_trii = self.background_mesh.triangles_points_index[other_tri_i]
                                    other_trii_new0, other_trii_new1 = cGrid.least_angle_trii(self, e01_at[0], np.setdiff1d(other_trii, e01_at)[0], x_ga_index, e01_at[1])

                                    self.enriched_mesh.triangles_points_index[other_tri_i] = other_trii_new0
                                    self.enriched_mesh.triangles_points_index = np.vstack((self.enriched_mesh.triangles_points_index, other_trii_new1))

                                    self.has_edge_been_handled[j02] = np.array([p02_ga_index, p02_at_index])

                                    self.enriched_mesh.n_tri = self.enriched_mesh.n_tri + 4
                                    self.enriched_mesh.n = self.enriched_mesh.n + 3
#                                    trii0 = np.hstack((np.setdiff1d(e02, e01_at)[0], p01_ga_index, x_ga_index))
#                                    self.enriched_mesh.triangles_points_index[i] = trii0
#
#                                    other_tri_i = np.setdiff1d(self.background_mesh.edge_in_tri[j01_at], i)[0]
#                                    other_trii = self.background_mesh.triangles_points_index[other_tri_i]
#                                    other_trii_new0, other_trii_new1 = cGrid.least_angle_trii(self, e01_at[0], np.setdiff1d(other_trii, e01_at)[0], x_ga_index, e01_at[1])
#                                    self.enriched_mesh.triangles_points_index[other_tri_i] = other_trii_new0
#                                    self.enriched_mesh.triangles_points_index = np.vstack((self.enriched_mesh.triangles_points_index, other_trii_new1))
#
#                                    other_tri_e02 = np.setdiff1d(self.background_mesh.edge_in_tri[j02], i)[0]
#                                    other_trii = self.background_mesh.triangles_points_index[other_tri_e02]
#                                    other_trii_new0 = np.hstack((e01_at[0], np.setdiff1d(other_trii, e02)[0], x_ga_index))
#                                    other_trii_new1 = np.hstack((e01_at[1], np.setdiff1d(other_trii, e02)[0], x_ga_index))
#
#                                    self.enriched_mesh.triangles_points_index[other_tri_e02] = other_trii_new0
#                                    self.enriched_mesh.triangles_points_index = np.vstack((self.enriched_mesh.triangles_points_index, other_trii_new1))
#
#                                    self.enriched_mesh.n_tri = self.enriched_mesh.n_tri + 2
#                                    self.enriched_mesh.n = self.enriched_mesh.n + 1

                                elif lambda_barycentric[np.where(trii == p01_ga_index)[0]] < self.delta: #then bend to e02
                                    print('bend on e02 edge')
                                    p01_at_index = self.enriched_mesh.n + 1
                                    self.enriched_mesh.points = np.vstack((self.enriched_mesh.points, p01_at))

                                    phi_ga_pe = self.level_set_gammaalpha_enriched.interpolate(trii, tri, p01_at)
                                    if phi_ga_pe < 0:
                                        self.has_point_been_shifted = np.vstack((self.has_point_been_shifted, [1, 3]))
                                    else:
                                        self.has_point_been_shifted = np.vstack((self.has_point_been_shifted, [1, 2]))
                                    self.level_set_gammaalpha_enriched.phi = np.hstack((self.level_set_gammaalpha_enriched.phi, phi_ga_pe))
                                    self.level_set_alphatheta_enriched.phi = np.hstack((self.level_set_alphatheta_enriched.phi, 0))

                                    cut_Tau = np.zeros(self.background_mesh.n+1)
                                    cut_Tau[[e01_at]] = np.array([1-taue01_at, taue01_at])
                                    if self.background_mesh.Tau[e01_at[0], e01_at[0]] != 0:
                                        other_points = self.background_mesh.Tau[e01_at[0]].nonzero()[1]
                                        cut_Tau[e01_at[0]] = 0
                                        cut_Tau[[other_points]] = cut_Tau[[other_points]] + (1-taue01_at) * self.background_mesh.Tau[e01_at[0], other_points].toarray()
                                    if self.background_mesh.Tau[e01_at[1], e01_at[1]] != 0:
                                        other_points = self.background_mesh.Tau[e01_at[1]].nonzero()[1]
                                        cut_Tau[e01_at[1]] = 0
                                        cut_Tau[[other_points]] = cut_Tau[[other_points]] + taue01_at * self.background_mesh.Tau[e01_at[1], other_points].toarray()
                                    cut_Tau[self.background_mesh.n] = p01_at_index
                                    self.background_mesh.Tau = vstack((self.background_mesh.Tau, cut_Tau), format = 'lil')

#                                    trii0, trii1 = cGrid.least_angle_trii(self, p01_ga_index, np.setdiff1d(e02, e01_at)[0], p01_at_index, x_ga_index)
                                    trii0 = np.hstack((p01_ga_index, p01_at_index, x_ga_index))
                                    trii1 = np.hstack((p01_ga_index, np.setdiff1d(e02, e01_at)[0], x_ga_index))
                                    trii2 = np.hstack((np.intersect1d(e02, e01_at)[0], p01_at_index, x_ga_index))

                                    self.enriched_mesh.triangles_points_index[i] = trii0
                                    self.enriched_mesh.triangles_points_index = np.vstack((self.enriched_mesh.triangles_points_index, trii1, trii2))

                                    other_tri_i = np.setdiff1d(self.background_mesh.edge_in_tri[j02], i)[0]
                                    other_trii = self.background_mesh.triangles_points_index[other_tri_i]
                                    other_trii_new0, other_trii_new1 = cGrid.least_angle_trii(self, e02[0], np.setdiff1d(other_trii, e02)[0], x_ga_index, e02[1])

                                    self.enriched_mesh.triangles_points_index[other_tri_i] = other_trii_new0
                                    self.enriched_mesh.triangles_points_index = np.vstack((self.enriched_mesh.triangles_points_index, other_trii_new1))

                                    self.has_edge_been_handled[j01_at] = p01_at_index

                                    self.enriched_mesh.n_tri = self.enriched_mesh.n_tri + 3
                                    self.enriched_mesh.n = self.enriched_mesh.n + 2
                                elif lambda_barycentric[np.where(trii == np.intersect1d(e02, e01_at)[0])[0]] < self.delta: #then bend to other edge
                                    print('bend on other edge, IF THIS HAPPENS ENRICHED MESH IS REALLY UGLY AROUND TRIPLE POINT')
                                    p01_at_index = self.enriched_mesh.n + 1
                                    p02_at_index = self.enriched_mesh.n + 2
                                    p02_ga_index = self.enriched_mesh.n + 3
                                    e_other = np.sort([p01_ga_index, np.setdiff1d(e02, e01_at)[0]])
                                    j_other = self.enriched_mesh.edge_to_index[e_other[0],e_other[1]]

                                    self.enriched_mesh.points = np.vstack((self.enriched_mesh.points, p01_at, p02_at, p02_ga))

                                    phi_ga_pe01 = self.level_set_gammaalpha_enriched.interpolate(trii, tri, p01_at)
                                    phi_ga_pe02 = self.level_set_gammaalpha_enriched.interpolate(trii, tri, p02_at)
                                    if phi_ga_pe01 < 0:
                                        self.has_point_been_shifted = np.vstack((self.has_point_been_shifted, [1, 3]))
                                    else:
                                        self.has_point_been_shifted = np.vstack((self.has_point_been_shifted, [1, 2]))
                                    if phi_ga_pe02 < 0:
                                        self.has_point_been_shifted = np.vstack((self.has_point_been_shifted, [1, 3]))
                                    else:
                                        self.has_point_been_shifted = np.vstack((self.has_point_been_shifted, [1, 2]))
                                    if phi_ga_pe01 * phi_ga_pe02 > 0:
                                        print('both theta points alpha or gamma-theta!')
                                    if self.has_point_been_shifted[p01_ga_index,1] == 11:
                                        self.has_point_been_shifted = np.vstack((self.has_point_been_shifted, [1, 1]))
                                    elif self.has_point_been_shifted[p01_ga_index,1] == 1:
                                        self.has_point_been_shifted = np.vstack((self.has_point_been_shifted, [1, 11]))
                                    else:
                                        print('p01_ga_index not ga?')
                                    self.level_set_gammaalpha_enriched.phi = np.hstack((self.level_set_gammaalpha_enriched.phi,
                                                                                        phi_ga_pe01, phi_ga_pe02, 0))
                                    self.level_set_alphatheta_enriched.phi = np.hstack((self.level_set_alphatheta_enriched.phi, np.zeros(2),
                                                                                        self.level_set_alphatheta_enriched.interpolate(trii, tri, p02_ga)))

                                    cut_Tau = np.zeros(self.background_mesh.n+1)
                                    cut_Tau[[e01_at]] = np.array([1-taue01_at, taue01_at])
                                    if self.background_mesh.Tau[e01_at[0], e01_at[0]] != 0:
                                        other_points = self.background_mesh.Tau[e01_at[0]].nonzero()[1]
                                        cut_Tau[e01_at[0]] = 0
                                        cut_Tau[[other_points]] = cut_Tau[[other_points]] + (1-taue01_at) * self.background_mesh.Tau[e01_at[0], other_points].toarray()
                                    if self.background_mesh.Tau[e01_at[1], e01_at[1]] != 0:
                                        other_points = self.background_mesh.Tau[e01_at[1]].nonzero()[1]
                                        cut_Tau[e01_at[1]] = 0
                                        cut_Tau[[other_points]] = cut_Tau[[other_points]] + taue01_at * self.background_mesh.Tau[e01_at[1], other_points].toarray()
                                    cut_Tau[self.background_mesh.n] = p01_at_index
                                    self.background_mesh.Tau = vstack((self.background_mesh.Tau, cut_Tau), format = 'lil')

                                    cut_Tau = np.zeros(self.background_mesh.n+1)
                                    cut_Tau[[e02]] = np.array([1-taue02_at, taue02_at])
                                    if self.background_mesh.Tau[e02[0], e02[0]] != 0:
                                        other_points = self.background_mesh.Tau[e02[0]].nonzero()[1]
                                        cut_Tau[e02[0]] = 0
                                        cut_Tau[[other_points]] = cut_Tau[[other_points]] + (1-taue02_at) * self.background_mesh.Tau[e02[0], other_points].toarray()
                                    if self.background_mesh.Tau[e02[1], e02[1]] != 0:
                                        other_points = self.background_mesh.Tau[e02[1]].nonzero()[1]
                                        cut_Tau[e02[1]] = 0
                                        cut_Tau[[other_points]] = cut_Tau[[other_points]] + taue02_at * self.background_mesh.Tau[e02[1], other_points].toarray()
                                    cut_Tau[self.background_mesh.n] = p02_at_index
                                    self.background_mesh.Tau = vstack((self.background_mesh.Tau, cut_Tau), format = 'lil')

                                    cut_Tau = np.zeros(self.background_mesh.n+1)
                                    cut_Tau[[e02]] = np.array([1-taue02_ga, taue02_ga])
                                    if self.background_mesh.Tau[e02[0], e02[0]] != 0:
                                        other_points = self.background_mesh.Tau[e02[0]].nonzero()[1]
                                        cut_Tau[e02[0]] = 0
                                        cut_Tau[[other_points]] = cut_Tau[[other_points]] + (1-taue02_ga) * self.background_mesh.Tau[e02[0], other_points].toarray()
                                    if self.background_mesh.Tau[e02[1], e02[1]] != 0:
                                        other_points = self.background_mesh.Tau[e02[1]].nonzero()[1]
                                        cut_Tau[e02[1]] = 0
                                        cut_Tau[[other_points]] = cut_Tau[[other_points]] + taue02_ga * self.background_mesh.Tau[e02[1], other_points].toarray()
                                    cut_Tau[self.background_mesh.n] = p02_ga_index
                                    self.background_mesh.Tau = vstack((self.background_mesh.Tau, cut_Tau), format = 'lil')

                                    trii0 = np.hstack((p01_ga_index, p01_at_index, x_ga_index))
                                    trii1, trii2 = cGrid.least_angle_trii(self, np.setdiff1d(e01_at, p01_ga_index)[0], p01_at_index, p02_ga_index, x_ga_index)
                                    trii3 = np.hstack((np.setdiff1d(e_other, p01_ga_index)[0], p02_at_index, x_ga_index))
                                    trii4 = np.hstack((p02_at_index, p02_ga_index, x_ga_index))

                                    self.enriched_mesh.triangles_points_index[i] = trii0
                                    self.enriched_mesh.triangles_points_index = np.vstack((self.enriched_mesh.triangles_points_index, trii1, trii2, trii3, trii4))

                                    other_tri_i = np.setdiff1d(self.background_mesh.edge_in_tri[j_other], i)[0]
                                    other_trii = self.background_mesh.triangles_points_index[other_tri_i]
                                    other_trii_new0, other_trii_new1 = cGrid.least_angle_trii(self, e_other[0], np.setdiff1d(other_trii, e_other)[0], x_ga_index, e_other[1])

                                    self.enriched_mesh.triangles_points_index[other_tri_i] = other_trii_new0
                                    self.enriched_mesh.triangles_points_index = np.vstack((self.enriched_mesh.triangles_points_index, other_trii_new1))

                                    self.has_edge_been_handled[j02] = np.array([p02_ga_index, p02_at_index])
                                    self.has_edge_been_handled[j01_at] = p01_at_index

                                    self.enriched_mesh.n_tri = self.enriched_mesh.n_tri + 5
                                    self.enriched_mesh.n = self.enriched_mesh.n + 4
                                else:
                                    print('something weird')
                            elif at == 0: #ga == 1  bend 110
                                x_ga_index = self.enriched_mesh.n + 0
                                self.enriched_mesh.points = np.vstack((self.enriched_mesh.points, x_ga))
                                self.has_point_been_shifted = np.vstack((self.has_point_been_shifted, [1, 12]))
                                self.level_set_gammaalpha_enriched.phi = np.hstack((self.level_set_gammaalpha_enriched.phi, 0))
                                self.level_set_alphatheta_enriched.phi = np.hstack((self.level_set_alphatheta_enriched.phi, 0))
                                #Find out which edge triple point is close to, could be any of the three
                                where_lambda_small, = np.where(lambda_barycentric < self.delta)
                                if trii[where_lambda_small][0] == p01_at_index: #then triple point shifts on e02
                                    print('bend on e02 edge')
                                    p01_ga_index = self.enriched_mesh.n + 1
                                    self.enriched_mesh.points = np.vstack((self.enriched_mesh.points, p01_ga))
                                    phi_at_pe = self.level_set_alphatheta_enriched.interpolate(trii, tri, p01_ga)
                                    if phi_at_pe < 0:
                                        self.has_point_been_shifted = np.vstack((self.has_point_been_shifted, [1, 1]))
                                    else:
                                        self.has_point_been_shifted = np.vstack((self.has_point_been_shifted, [1, 11]))
                                    self.level_set_gammaalpha_enriched.phi = np.hstack((self.level_set_gammaalpha_enriched.phi, 0))
                                    self.level_set_alphatheta_enriched.phi = np.hstack((self.level_set_alphatheta_enriched.phi, phi_at_pe))

                                    cut_Tau = np.zeros(self.background_mesh.n+1)
                                    cut_Tau[[e01_ga]] = np.array([1-taue01_ga, taue01_ga])
                                    if self.background_mesh.Tau[e01_ga[0], e01_ga[0]] != 0:
                                        other_points = self.background_mesh.Tau[e01_ga[0]].nonzero()[1]
                                        cut_Tau[e01_ga[0]] = 0
                                        cut_Tau[[other_points]] = cut_Tau[[other_points]] + (1-taue01_ga) * self.background_mesh.Tau[e01_ga[0], other_points].toarray()
                                    if self.background_mesh.Tau[e01_ga[1], e01_ga[1]] != 0:
                                        other_points = self.background_mesh.Tau[e01_ga[1]].nonzero()[1]
                                        cut_Tau[e01_ga[1]] = 0
                                        cut_Tau[[other_points]] = cut_Tau[[other_points]] + taue01_ga * self.background_mesh.Tau[e01_ga[1], other_points].toarray()
                                    cut_Tau[self.background_mesh.n] = p01_ga_index
                                    self.background_mesh.Tau = vstack((self.background_mesh.Tau, cut_Tau), format = 'lil')

                                    trii0 = np.hstack((np.setdiff1d(e02, e01_ga)[0], p01_at_index, x_ga_index))
                                    trii1 = np.hstack((np.intersect1d(e02, e01_ga)[0], p01_ga_index, x_ga_index))
                                    trii2 = np.hstack((p01_at_index, p01_ga_index, x_ga_index))

                                    self.enriched_mesh.triangles_points_index[i] = trii2
                                    self.enriched_mesh.triangles_points_index = np.vstack((self.enriched_mesh.triangles_points_index, trii0, trii1))

                                    other_tri_i = np.setdiff1d(self.background_mesh.edge_in_tri[j02], i)[0]
                                    other_trii = self.background_mesh.triangles_points_index[other_tri_i]
                                    other_trii_new0, other_trii_new1 = cGrid.least_angle_trii(self, e02[0], np.setdiff1d(other_trii, e02)[0], x_ga_index, e02[1])

                                    self.enriched_mesh.triangles_points_index[other_tri_i] = other_trii_new0
                                    self.enriched_mesh.triangles_points_index = np.vstack((self.enriched_mesh.triangles_points_index, other_trii_new1))

                                    self.has_edge_been_handled[j01_ga] = p01_ga_index

                                    self.enriched_mesh.n_tri = self.enriched_mesh.n_tri + 3
                                    self.enriched_mesh.n = self.enriched_mesh.n + 2
                                #bend with 2 cuts
                                elif trii[where_lambda_small][0] == np.setdiff1d(e02, e01_ga)[0]: #triple on e01_ga
                                    p02_at_index = self.enriched_mesh.n + 1
                                    print('bend on e01_ga edge')
                                    self.enriched_mesh.points = np.vstack((self.enriched_mesh.points, p02_at))
                                    phi_ga_pe = self.level_set_gammaalpha_enriched.interpolate(trii, tri, p02_at)
                                    if phi_ga_pe < 0:
                                        self.has_point_been_shifted = np.vstack((self.has_point_been_shifted, [1, 3]))
                                    else:
                                        self.has_point_been_shifted = np.vstack((self.has_point_been_shifted, [1, 2]))
                                    self.level_set_gammaalpha_enriched.phi = np.hstack((self.level_set_gammaalpha_enriched.phi, phi_ga_pe))
                                    self.level_set_alphatheta_enriched.phi = np.hstack((self.level_set_alphatheta_enriched.phi, 0))

                                    cut_Tau = np.zeros(self.background_mesh.n+1)
                                    cut_Tau[[e02]] = np.array([1-taue02_at, taue02_at])
                                    if self.background_mesh.Tau[e02[0], e02[0]] != 0:
                                        other_points = self.background_mesh.Tau[e02[0]].nonzero()[1]
                                        cut_Tau[e02[0]] = 0
                                        cut_Tau[[other_points]] = cut_Tau[[other_points]] + (1-taue02_at) * self.background_mesh.Tau[e02[0], other_points].toarray()
                                    if self.background_mesh.Tau[e02[1], e02[1]] != 0:
                                        other_points = self.background_mesh.Tau[e02[1]].nonzero()[1]
                                        cut_Tau[e02[1]] = 0
                                        cut_Tau[[other_points]] = cut_Tau[[other_points]] + taue02_at * self.background_mesh.Tau[e02[1], other_points].toarray()
                                    cut_Tau[self.background_mesh.n] = p02_at_index
                                    self.background_mesh.Tau = vstack((self.background_mesh.Tau, cut_Tau), format = 'lil')

                                    p02_ga_index = self.enriched_mesh.n + 2
                                    self.enriched_mesh.points = np.vstack((self.enriched_mesh.points, p02_ga))
                                    phi_at_pe = self.level_set_alphatheta_enriched.interpolate(trii, tri, p02_ga)
                                    if phi_at_pe < 0:
                                        self.has_point_been_shifted = np.vstack((self.has_point_been_shifted, [1, 1]))
                                    else:
                                        self.has_point_been_shifted = np.vstack((self.has_point_been_shifted, [1, 11]))
                                    self.level_set_gammaalpha_enriched.phi = np.hstack((self.level_set_gammaalpha_enriched.phi, 0))
                                    self.level_set_alphatheta_enriched.phi = np.hstack((self.level_set_alphatheta_enriched.phi, phi_at_pe))

                                    cut_Tau = np.zeros(self.background_mesh.n+1)
                                    cut_Tau[[e02]] = np.array([1-taue02_ga, taue02_ga])
                                    if self.background_mesh.Tau[e02[0], e02[0]] != 0:
                                        other_points = self.background_mesh.Tau[e02[0]].nonzero()[1]
                                        cut_Tau[e02[0]] = 0
                                        cut_Tau[[other_points]] = cut_Tau[[other_points]] + (1-taue02_ga) * self.background_mesh.Tau[e02[0], other_points].toarray()
                                    if self.background_mesh.Tau[e02[1], e02[1]] != 0:
                                        other_points = self.background_mesh.Tau[e02[1]].nonzero()[1]
                                        cut_Tau[e02[1]] = 0
                                        cut_Tau[[other_points]] = cut_Tau[[other_points]] + taue02_ga * self.background_mesh.Tau[e02[1], other_points].toarray()
                                    cut_Tau[self.background_mesh.n] = p02_ga_index
                                    self.background_mesh.Tau = vstack((self.background_mesh.Tau, cut_Tau), format = 'lil')

                                    trii0, trii1 = cGrid.least_angle_trii(self, p01_at_index, np.setdiff1d(e02, e01_ga)[0], x_ga_index, p02_ga_index)
                                    trii2 = np.hstack((p02_at_index, p02_ga_index, x_ga_index))
                                    trii3 = np.hstack((np.intersect1d(e02, e01_ga)[0], p02_at_index, x_ga_index))

                                    self.enriched_mesh.triangles_points_index[i] = trii0
                                    self.enriched_mesh.triangles_points_index = np.vstack((self.enriched_mesh.triangles_points_index, trii1, trii2, trii3))

                                    other_tri_i = np.setdiff1d(self.background_mesh.edge_in_tri[j01_ga], i)[0]
                                    other_trii = self.background_mesh.triangles_points_index[other_tri_i]
                                    other_trii_new0, other_trii_new1 = cGrid.least_angle_trii(self, e01_ga[0], np.setdiff1d(other_trii, e01_ga)[0], x_ga_index, e01_ga[1])

                                    self.enriched_mesh.triangles_points_index[other_tri_i] = other_trii_new0
                                    self.enriched_mesh.triangles_points_index = np.vstack((self.enriched_mesh.triangles_points_index, other_trii_new1))

                                    self.has_edge_been_handled[j02] = np.array([p02_ga_index, p02_at_index])

                                    self.enriched_mesh.n_tri = self.enriched_mesh.n_tri + 4
                                    self.enriched_mesh.n = self.enriched_mesh.n + 3
#                                #bend with flip edge e02
#                                elif trii[where_lambda_small][0] == np.setdiff1d(e02, e01_ga)[0]: #triple on e01_ga
#                                    print('bend on e01_ga edge')
#
#
#                                    trii0 = np.hstack((p01_at_index, np.setdiff1d(e02, e01_ga)[0], x_ga_index))
#                                    self.enriched_mesh.triangles_points_index[i] = trii0
#
#                                    other_tri_i = np.setdiff1d(self.background_mesh.edge_in_tri[j01_ga], i)[0]
#                                    other_trii = self.background_mesh.triangles_points_index[other_tri_i]
#                                    other_trii_new0, other_trii_new1 = cGrid.least_angle_trii(self, e01_ga[0], np.setdiff1d(other_trii, e01_ga)[0], x_ga_index, e01_ga[1])
#
#                                    self.enriched_mesh.triangles_points_index[other_tri_i] = other_trii_new0
#                                    self.enriched_mesh.triangles_points_index = np.vstack((self.enriched_mesh.triangles_points_index, other_trii_new1))
#
#                                    other_tri_e02 = np.setdiff1d(self.background_mesh.edge_in_tri[j02], i)[0]
#                                    other_trii_e02 = self.background_mesh.triangles_points_index[other_tri_e02]
#                                    other_trii_new0 = np.hstack((e02[0], np.setdiff1d(other_trii_e02, e02)[0], x_ga_index))
#                                    other_trii_new1 = np.hstack((e02[1], np.setdiff1d(other_trii_e02, e02)[0], x_ga_index))
#                                    self.enriched_mesh.triangles_points_index[other_tri_e02] = other_trii_new0
#                                    self.enriched_mesh.triangles_points_index = np.vstack((self.enriched_mesh.triangles_points_index, other_trii_new1))
#
##                                    self.has_edge_been_handled[j02] = np.array([p02_ga_index, p02_at_index])
##                                        self.has_edge_been_handled[j01_ga] = x_ga_index
#
##                                        self.interface_gammaalpha.edges_index = np.vstack((self.interface_gammaalpha.edges_index, np.sort([p02_ga_index, x_ga_index])))
##                                        self.interface_alphatheta.edges_index = np.vstack((self.interface_alphatheta.edges_index, np.sort([p01_at_index, x_ga_index]), np.array([p02_at_index, x_ga_index])))
#
#                                    self.enriched_mesh.n_tri = self.enriched_mesh.n_tri + 2
#                                    self.enriched_mesh.n = self.enriched_mesh.n + 1
                                elif trii[where_lambda_small][0] == np.intersect1d(e02, e01_ga)[0]: #triple on third edge
                                    print('added on other edge, does not happen too often.')
                                    p02_at_index = self.enriched_mesh.n + 1
                                    self.enriched_mesh.points = np.vstack((self.enriched_mesh.points, p02_at))
                                    phi_ga_pe = self.level_set_gammaalpha_enriched.interpolate(trii, tri, p02_at)
                                    if phi_ga_pe < 0:
                                        self.has_point_been_shifted = np.vstack((self.has_point_been_shifted, [1, 3]))
                                    else:
                                        self.has_point_been_shifted = np.vstack((self.has_point_been_shifted, [1, 2]))
                                    self.level_set_gammaalpha_enriched.phi = np.hstack((self.level_set_gammaalpha_enriched.phi, phi_ga_pe))
                                    self.level_set_alphatheta_enriched.phi = np.hstack((self.level_set_alphatheta_enriched.phi, 0))

                                    cut_Tau = np.zeros(self.background_mesh.n+1)
                                    cut_Tau[[e02]] = np.array([1-taue02_at, taue02_at])
                                    if self.background_mesh.Tau[e02[0], e02[0]] != 0:
                                        other_points = self.background_mesh.Tau[e02[0]].nonzero()[1]
                                        cut_Tau[e02[0]] = 0
                                        cut_Tau[[other_points]] = cut_Tau[[other_points]] + (1-taue02_at) * self.background_mesh.Tau[e02[0], other_points].toarray()
                                    if self.background_mesh.Tau[e02[1], e02[1]] != 0:
                                        other_points = self.background_mesh.Tau[e02[1]].nonzero()[1]
                                        cut_Tau[e02[1]] = 0
                                        cut_Tau[[other_points]] = cut_Tau[[other_points]] + taue02_at * self.background_mesh.Tau[e02[1], other_points].toarray()
                                    cut_Tau[self.background_mesh.n] = p02_at_index
                                    self.background_mesh.Tau = vstack((self.background_mesh.Tau, cut_Tau), format = 'lil')
#
                                    p01_ga_index = self.enriched_mesh.n + 2
                                    self.enriched_mesh.points = np.vstack((self.enriched_mesh.points, p01_ga))
                                    phi_at_pe = self.level_set_alphatheta_enriched.interpolate(trii, tri, p01_ga)
                                    if phi_at_pe < 0:
                                        self.has_point_been_shifted = np.vstack((self.has_point_been_shifted, [1, 1]))
                                    else:
                                        self.has_point_been_shifted = np.vstack((self.has_point_been_shifted, [1, 11]))
                                    self.level_set_gammaalpha_enriched.phi = np.hstack((self.level_set_gammaalpha_enriched.phi, 0))
                                    self.level_set_alphatheta_enriched.phi = np.hstack((self.level_set_alphatheta_enriched.phi, phi_at_pe))

                                    cut_Tau = np.zeros(self.background_mesh.n+1)
                                    cut_Tau[[e01_ga]] = np.array([1-taue01_ga, taue01_ga])
                                    if self.background_mesh.Tau[e01_ga[0], e01_ga[0]] != 0:
                                        other_points = self.background_mesh.Tau[e01_ga[0]].nonzero()[1]
                                        cut_Tau[e01_ga[0]] = 0
                                        cut_Tau[[other_points]] = cut_Tau[[other_points]] + (1-taue01_ga) * self.background_mesh.Tau[e01_ga[0], other_points].toarray()
                                    if self.background_mesh.Tau[e01_ga[1], e01_ga[1]] != 0:
                                        other_points = self.background_mesh.Tau[e01_ga[1]].nonzero()[1]
                                        cut_Tau[e01_ga[1]] = 0
                                        cut_Tau[[other_points]] = cut_Tau[[other_points]] + taue01_ga * self.background_mesh.Tau[e01_ga[1], other_points].toarray()
                                    cut_Tau[self.background_mesh.n] = p01_ga_index
                                    self.background_mesh.Tau = vstack((self.background_mesh.Tau, cut_Tau), format = 'lil')

                                    p02_ga_index = self.enriched_mesh.n + 3
                                    self.enriched_mesh.points = np.vstack((self.enriched_mesh.points, p02_ga))
                                    phi_at_pe = self.level_set_alphatheta_enriched.interpolate(trii, tri, p02_ga)
                                    if phi_at_pe < 0:
                                        self.has_point_been_shifted = np.vstack((self.has_point_been_shifted, [1, 1]))
                                    else:
                                        self.has_point_been_shifted = np.vstack((self.has_point_been_shifted, [1, 11]))
                                    self.level_set_gammaalpha_enriched.phi = np.hstack((self.level_set_gammaalpha_enriched.phi, 0))
                                    self.level_set_alphatheta_enriched.phi = np.hstack((self.level_set_alphatheta_enriched.phi, phi_at_pe))

                                    cut_Tau = np.zeros(self.background_mesh.n+1)
                                    cut_Tau[[e02]] = np.array([1-taue02_ga, taue02_ga])
                                    if self.background_mesh.Tau[e02[0], e02[0]] != 0:
                                        other_points = self.background_mesh.Tau[e02[0]].nonzero()[1]
                                        cut_Tau[e02[0]] = 0
                                        cut_Tau[[other_points]] = cut_Tau[[other_points]] + (1-taue02_ga) * self.background_mesh.Tau[e02[0], other_points].toarray()
                                    if self.background_mesh.Tau[e02[1], e02[1]] != 0:
                                        other_points = self.background_mesh.Tau[e02[1]].nonzero()[1]
                                        cut_Tau[e02[1]] = 0
                                        cut_Tau[[other_points]] = cut_Tau[[other_points]] + taue02_ga * self.background_mesh.Tau[e02[1], other_points].toarray()
                                    cut_Tau[self.background_mesh.n] = p02_at_index
                                    self.background_mesh.Tau = vstack((self.background_mesh.Tau, cut_Tau), format = 'lil')

                                    trii0, trii1 = cGrid.least_angle_trii(self, np.intersect1d(e02, e01_ga)[0], p02_at_index, p01_ga_index, x_ga_index)
                                    trii2 = np.hstack((p01_at_index, p01_ga_index, x_ga_index))
                                    trii3 = np.hstack((np.setdiff1d(e02, e01_ga)[0], p02_ga_index, x_ga_index))
                                    trii4 = np.hstack((p02_ga_index, p02_at_index, x_ga_index))

                                    self.enriched_mesh.triangles_points_index[i] = trii2
                                    self.enriched_mesh.triangles_points_index = np.vstack((self.enriched_mesh.triangles_points_index, trii0, trii1, trii3, trii4))

                                    e_other = np.sort([p01_at_index, np.setdiff1d(e02, e01_ga)[0]])
                                    j_other = self.enriched_mesh.edge_to_index[e_other[0],e_other[1]]

                                    other_tri_i = np.setdiff1d(self.background_mesh.edge_in_tri[j_other], i)[0]
                                    other_trii = self.background_mesh.triangles_points_index[other_tri_i]
                                    other_trii_new0, other_trii_new1 = cGrid.least_angle_trii(self, e_other[0], np.setdiff1d(other_trii, e_other)[0], x_ga_index, e_other[1])

                                    self.enriched_mesh.triangles_points_index[other_tri_i] = other_trii_new0
                                    self.enriched_mesh.triangles_points_index = np.vstack((self.enriched_mesh.triangles_points_index, other_trii_new1))

                                    self.has_edge_been_handled[j02] = np.hstack((p02_ga_index, p02_at_index))
                                    self.has_edge_been_handled[j01_ga] = p01_ga_index

                                    self.enriched_mesh.n_tri = self.enriched_mesh.n_tri + 6
                                    self.enriched_mesh.n = self.enriched_mesh.n + 4


                        elif ga_at == 2: #bend 200
                            x_ga_index  = self.enriched_mesh.n + 0
                            p2_at_index = self.enriched_mesh.n + 1
                            #have to find out which edge it shifts to as two edges have both interfaces crossing
                            if lambda_barycentric[np.where(trii == np.setdiff1d(trii, e02)[0])[0]] < self.delta: #then e02 is the edge triple point shifts to
                                print('bend on e02')
                                p2_ga = p12_ga
                                p2_at = p12_at
                                e2_shift = e02
                                e2_other = e12
                                j2_shift = j02
                                j2_other = j12
                                taue2_at_shift = taue02_at
                                taue2_at_other = taue12_at
                                taue2_ga_shift = taue02_ga
                                taue2_ga_other = taue12_ga
                            elif lambda_barycentric[np.where(trii == np.setdiff1d(trii, e12)[0])[0]] < self.delta: #e12
                                print('bend on e12')
                                p2_ga = p02_ga
                                p2_at = p02_at
                                e2_shift = e12
                                e2_other = e02
                                j2_shift = j12
                                j2_other = j02
                                taue2_at_shift = taue12_at
                                taue2_at_other = taue02_at
                                taue2_ga_shift = taue12_ga
                                taue2_ga_other = taue02_ga
                            else:
                                print('bend edge on other edge, should not be possible (?)')

                            self.enriched_mesh.points = np.vstack((self.enriched_mesh.points, x_ga, p2_at))

                            phi_ga_pe = self.level_set_gammaalpha_enriched.interpolate(trii, tri, p2_at)
                            if phi_ga_pe < 0:
                                self.has_point_been_shifted = np.vstack((self.has_point_been_shifted, [1, 12], [1, 3]))
                            else:
                                self.has_point_been_shifted = np.vstack((self.has_point_been_shifted, [1, 12], [1, 2]))
                            self.level_set_gammaalpha_enriched.phi = np.hstack((self.level_set_gammaalpha_enriched.phi, 0, phi_ga_pe))
                            self.level_set_alphatheta_enriched.phi = np.hstack((self.level_set_alphatheta_enriched.phi, np.zeros(2)))

                            cut_Tau = np.zeros(self.background_mesh.n+1)
                            cut_Tau[[e2_other]] = np.array([1-taue2_at_other, taue2_at_other])
                            if self.background_mesh.Tau[e2_other[0], e2_other[0]] != 0:
                                other_points = self.background_mesh.Tau[e2_other[0]].nonzero()[1]
                                cut_Tau[e2_other[0]] = 0
                                cut_Tau[[other_points]] = cut_Tau[[other_points]] + (1-taue2_at_other) * self.background_mesh.Tau[e2_other[0], other_points].toarray()
                            if self.background_mesh.Tau[e2_other[1], e2_other[1]] != 0:
                                other_points = self.background_mesh.Tau[e2_other[1]].nonzero()[1]
                                cut_Tau[e2_other[1]] = 0
                                cut_Tau[[other_points]] = cut_Tau[[other_points]] + taue2_at_other * self.background_mesh.Tau[e2_other[1], other_points].toarray()
                            cut_Tau[self.background_mesh.n] = p2_at_index
                            self.background_mesh.Tau = vstack((self.background_mesh.Tau, cut_Tau), format = 'lil')

                            p2_ga_index = self.enriched_mesh.n + 2
                            if la.norm(p2_ga - self.enriched_mesh.points[np.setdiff1d(trii, e2_shift)[0]], 2) > la.norm(p2_at - self.enriched_mesh.points[np.setdiff1d(trii, e2_shift)[0]], 2):
                                point4_tri_index = p2_at_index
                                point3_tri_index = p2_ga_index
                            else:
                                point4_tri_index = p2_ga_index
                                point3_tri_index = p2_at_index

                            self.enriched_mesh.points = np.vstack((self.enriched_mesh.points, p2_ga))
                            phi_at_pe = self.level_set_alphatheta_enriched.interpolate(trii, tri, p2_ga)
                            if phi_at_pe < 0:
                                self.has_point_been_shifted = np.vstack((self.has_point_been_shifted, [1, 1]))
                            else:
                                self.has_point_been_shifted = np.vstack((self.has_point_been_shifted, [1, 11]))
                            self.level_set_gammaalpha_enriched.phi = np.hstack((self.level_set_gammaalpha_enriched.phi, 0))
                            self.level_set_alphatheta_enriched.phi = np.hstack((self.level_set_alphatheta_enriched.phi, phi_at_pe))

                            cut_Tau = np.zeros(self.background_mesh.n+1)
                            cut_Tau[[e2_other]] = np.array([1-taue2_ga_other, taue2_ga_other])
                            if self.background_mesh.Tau[e2_other[0], e2_other[0]] != 0:
                                other_points = self.background_mesh.Tau[e2_other[0]].nonzero()[1]
                                cut_Tau[e2_other[0]] = 0
                                cut_Tau[[other_points]] = cut_Tau[[other_points]] + (1-taue2_ga_other) * self.background_mesh.Tau[e2_other[0], other_points].toarray()
                            if self.background_mesh.Tau[e2_other[1], e2_other[1]] != 0:
                                other_points = self.background_mesh.Tau[e2_other[1]].nonzero()[1]
                                cut_Tau[e2_other[1]] = 0
                                cut_Tau[[other_points]] = cut_Tau[[other_points]] + taue2_ga_other * self.background_mesh.Tau[e2_other[1], other_points].toarray()
                            cut_Tau[self.background_mesh.n] = p2_ga_index
                            self.background_mesh.Tau = vstack((self.background_mesh.Tau, cut_Tau), format = 'lil')

                            trii0, trii1 = cGrid.least_angle_trii(self, np.setdiff1d(e2_other, e2_shift)[0], np.setdiff1d(e2_shift, e2_other)[0], point4_tri_index, x_ga_index)
                            trii2 = np.hstack((np.intersect1d(e2_other, e2_shift)[0], point3_tri_index, x_ga_index))
                            trii3 = np.hstack((point4_tri_index, point3_tri_index, x_ga_index))

                            self.enriched_mesh.triangles_points_index[i] = trii2
                            self.enriched_mesh.triangles_points_index = np.vstack((self.enriched_mesh.triangles_points_index, trii0, trii1, trii3))

                            other_tri_i = np.setdiff1d(self.background_mesh.edge_in_tri[j2_shift], i)[0]
                            other_trii = self.background_mesh.triangles_points_index[other_tri_i]
                            other_trii_new0, other_trii_new1 = cGrid.least_angle_trii(self, e2_shift[0], np.setdiff1d(other_trii, e2_shift)[0], x_ga_index, e2_shift[1])

                            self.enriched_mesh.triangles_points_index[other_tri_i] = other_trii_new0
                            self.enriched_mesh.triangles_points_index = np.vstack((self.enriched_mesh.triangles_points_index, other_trii_new1))

                            self.has_edge_been_handled[j2_other] = np.array([p2_ga_index, p2_at_index])

                            self.enriched_mesh.n_tri = self.enriched_mesh.n_tri + 4
                            self.enriched_mesh.n = self.enriched_mesh.n + 3
                            #Flip edge other
#                            x_ga_index  = self.enriched_mesh.n + 0
#                            #have to find out which edge it shifts to as two edges have both interfaces crossing
#                            if lambda_barycentric[np.where(trii == np.setdiff1d(trii, e02)[0])[0]] < self.delta: #then e02 is the edge triple point shifts to
#                                print('bend on e02')
#                                p2_ga = p12_ga
#                                p2_at = p12_at
#                                e2_shift = e02
#                                e2_other = e12
#                                j2_shift = j02
#                                j2_other = j12
#                                taue2_at_shift = taue02_at
#                                taue2_at_other = taue12_at
#                                taue2_ga_shift = taue02_ga
#                                taue2_ga_other = taue12_ga
#                            elif lambda_barycentric[np.where(trii == np.setdiff1d(trii, e12)[0])[0]] < self.delta: #e12
#                                print('bend on e01')
#                                p2_ga = p02_ga
#                                p2_at = p02_at
#                                e2_shift = e12
#                                e2_other = e02
#                                j2_shift = j12
#                                j2_other = j02
#                                taue2_at_shift = taue12_at
#                                taue2_at_other = taue02_at
#                                taue2_ga_shift = taue12_ga
#                                taue2_ga_other = taue02_ga
#                            else:
#                                print('bend edge on other edge, should not be possible')
#
#                            self.enriched_mesh.points = np.vstack((self.enriched_mesh.points, x_ga))
#
#                            self.has_point_been_shifted = np.vstack((self.has_point_been_shifted, [1, 12]))
#                            self.level_set_gammaalpha_enriched.phi = np.hstack((self.level_set_gammaalpha_enriched.phi, 0))
#                            self.level_set_alphatheta_enriched.phi = np.hstack((self.level_set_alphatheta_enriched.phi, 0))
#
#
#                            trii0 = np.hstack((np.setdiff1d(e2_other, e2_shift)[0], np.setdiff1d(e2_shift, e2_other)[0], x_ga_index))
#                            self.enriched_mesh.triangles_points_index[i] = trii0
#
#                            other_tri_i = np.setdiff1d(self.background_mesh.edge_in_tri[j2_shift], i)[0]
#                            other_trii = self.background_mesh.triangles_points_index[other_tri_i]
#                            other_trii_new0, other_trii_new1 = cGrid.least_angle_trii(self, e2_shift[0], np.setdiff1d(other_trii, e2_shift)[0], x_ga_index, e2_shift[1])
#
#                            self.enriched_mesh.triangles_points_index[other_tri_i] = other_trii_new0
#                            self.enriched_mesh.triangles_points_index = np.vstack((self.enriched_mesh.triangles_points_index, other_trii_new1))
#
#                            other_tri_i_other = np.setdiff1d(self.background_mesh.edge_in_tri[j2_other], i)[0]
#                            other_trii = self.background_mesh.triangles_points_index[other_tri_i_other]
#                            other_trii_new0 = np.hstack((e2_other[0], np.setdiff1d(other_trii, e2_other)[0], x_ga_index))
#                            other_trii_new1 = np.hstack((e2_other[1], np.setdiff1d(other_trii, e2_other)[0], x_ga_index))
#
#                            self.enriched_mesh.triangles_points_index[other_tri_i_other] = other_trii_new0
#                            self.enriched_mesh.triangles_points_index = np.vstack((self.enriched_mesh.triangles_points_index, other_trii_new1))
#
#                            self.enriched_mesh.n_tri = self.enriched_mesh.n_tri + 2
#                            self.enriched_mesh.n = self.enriched_mesh.n + 1
                        elif ga_at == 0:
                            if ga == 1 and at == 1: #bend 011
                                x_ga_index = self.enriched_mesh.n + 0
                                self.enriched_mesh.points = np.vstack((self.enriched_mesh.points, x_ga))
                                self.has_point_been_shifted = np.vstack((self.has_point_been_shifted, [1, 12]))
                                self.level_set_gammaalpha_enriched.phi = np.hstack((self.level_set_gammaalpha_enriched.phi, 0))
                                self.level_set_alphatheta_enriched.phi = np.hstack((self.level_set_alphatheta_enriched.phi, 0))
                                if lambda_barycentric[np.where(trii == p11_at_index)[0]] < self.delta: #then e01_at is the edge triple point shifts to
                                    print('bend edge e01_at')
                                    p01_ga_index = self.enriched_mesh.n + 1
                                    self.enriched_mesh.points = np.vstack((self.enriched_mesh.points, p01_ga))
                                    if self.has_point_been_shifted[p11_ga_index,1] == 1:
                                        self.has_point_been_shifted = np.vstack((self.has_point_been_shifted, [1, 11]))
                                    elif self.has_point_been_shifted[p11_ga_index,1] == 11:
                                        self.has_point_been_shifted = np.vstack((self.has_point_been_shifted, [1, 1]))
                                    else:
                                        print('p11_ga not ga point?')
                                    self.level_set_gammaalpha_enriched.phi = np.hstack((self.level_set_gammaalpha_enriched.phi, 0))
                                    self.level_set_alphatheta_enriched.phi = np.hstack((self.level_set_alphatheta_enriched.phi,
                                                                                        self.level_set_alphatheta_enriched.interpolate(trii, tri, p01_ga)))

                                    cut_Tau = np.zeros(self.background_mesh.n+1)
                                    cut_Tau[[e01_ga]] = np.array([1-taue01_ga, taue01_ga])
                                    if self.background_mesh.Tau[e01_ga[0], e01_ga[0]] != 0:
                                        other_points = self.background_mesh.Tau[e01_ga[0]].nonzero()[1]
                                        cut_Tau[e01_ga[0]] = 0
                                        cut_Tau[[other_points]] = cut_Tau[[other_points]] + (1-taue01_ga) * self.background_mesh.Tau[e01_ga[0], other_points].toarray()
                                    if self.background_mesh.Tau[e01_ga[1], e01_ga[1]] != 0:
                                        other_points = self.background_mesh.Tau[e01_ga[1]].nonzero()[1]
                                        cut_Tau[e01_ga[1]] = 0
                                        cut_Tau[[other_points]] = cut_Tau[[other_points]] + taue01_ga * self.background_mesh.Tau[e01_ga[1], other_points].toarray()
                                    cut_Tau[self.background_mesh.n] = p01_ga_index
                                    self.background_mesh.Tau = vstack((self.background_mesh.Tau, cut_Tau), format = 'lil')

                                    trii0 = np.hstack((p11_ga_index, p11_at_index, x_ga_index))
                                    trii1 = np.hstack((e01_ga[0], p01_ga_index, x_ga_index))
                                    trii2 = np.hstack((e01_ga[1], p01_ga_index, x_ga_index))

                                    self.enriched_mesh.triangles_points_index[i] = trii0
                                    self.enriched_mesh.triangles_points_index = np.vstack((self.enriched_mesh.triangles_points_index, trii1, trii2))

                                    other_tri_i = np.setdiff1d(self.background_mesh.edge_in_tri[j01_at], i)[0]
                                    other_trii = self.background_mesh.triangles_points_index[other_tri_i]
                                    other_trii_new0, other_trii_new1 = cGrid.least_angle_trii(self, e01_at[0], np.setdiff1d(other_trii, e01_at)[0], x_ga_index, e01_at[1])
                                    other_trii_new0 = np.hstack((e01_at[0], np.setdiff1d(other_trii, e01_at)[0], x_ga_index))
                                    other_trii_new1 = np.hstack((e01_at[1], np.setdiff1d(other_trii, e01_at)[0], x_ga_index))

                                    self.enriched_mesh.triangles_points_index[other_tri_i] = other_trii_new0
                                    self.enriched_mesh.triangles_points_index = np.vstack((self.enriched_mesh.triangles_points_index, other_trii_new1))

                                    self.has_edge_been_handled[j01_ga] = p01_ga_index

                                    self.enriched_mesh.n_tri = self.enriched_mesh.n_tri + 3
                                    self.enriched_mesh.n = self.enriched_mesh.n + 2
                                elif lambda_barycentric[np.where(trii == p11_ga_index)[0]] < self.delta: #then e01_ga is the edge triple point shifts to
                                    print('bend edge e01_ga')
                                    p01_at_index = self.enriched_mesh.n + 1
                                    self.enriched_mesh.points = np.vstack((self.enriched_mesh.points, p01_at))

                                    phi_ga_pe = self.level_set_gammaalpha_enriched.interpolate(trii, tri, p01_at)
                                    if phi_ga_pe < 0:
                                        self.has_point_been_shifted = np.vstack((self.has_point_been_shifted, [1, 3]))
                                    else:
                                        self.has_point_been_shifted = np.vstack((self.has_point_been_shifted, [1, 2]))
                                    self.level_set_gammaalpha_enriched.phi = np.hstack((self.level_set_gammaalpha_enriched.phi, phi_ga_pe))
                                    self.level_set_alphatheta_enriched.phi = np.hstack((self.level_set_alphatheta_enriched.phi, 0))

                                    cut_Tau = np.zeros(self.background_mesh.n+1)
                                    cut_Tau[[e01_at]] = np.array([1-taue01_at, taue01_at])
                                    if self.background_mesh.Tau[e01_at[0], e01_at[0]] != 0:
                                        other_points = self.background_mesh.Tau[e01_at[0]].nonzero()[1]
                                        cut_Tau[e01_at[0]] = 0
                                        cut_Tau[[other_points]] = cut_Tau[[other_points]] + (1-taue01_at) * self.background_mesh.Tau[e01_at[0], other_points].toarray()
                                    if self.background_mesh.Tau[e01_at[1], e01_at[1]] != 0:
                                        other_points = self.background_mesh.Tau[e01_at[1]].nonzero()[1]
                                        cut_Tau[e01_at[1]] = 0
                                        cut_Tau[[other_points]] = cut_Tau[[other_points]] + taue01_at * self.background_mesh.Tau[e01_at[1], other_points].toarray()
                                    cut_Tau[self.background_mesh.n] = p01_at_index
                                    self.background_mesh.Tau = vstack((self.background_mesh.Tau, cut_Tau), format = 'lil')

                                    trii0 = np.hstack((p11_at_index, p11_ga_index, x_ga_index))
                                    trii1 = np.hstack((e01_at[0], p01_at_index, x_ga_index))
                                    trii2 = np.hstack((e01_at[1], p01_at_index, x_ga_index))

                                    self.enriched_mesh.triangles_points_index[i] = trii0
                                    self.enriched_mesh.triangles_points_index = np.vstack((self.enriched_mesh.triangles_points_index, trii1, trii2))

                                    other_tri_i = np.setdiff1d(self.background_mesh.edge_in_tri[j01_ga], i)[0]
                                    other_trii = self.background_mesh.triangles_points_index[other_tri_i]
                                    other_trii_new0, other_trii_new1 = cGrid.least_angle_trii(self, e01_ga[0], np.setdiff1d(other_trii, e01_ga)[0], x_ga_index, e01_ga[1])

                                    self.enriched_mesh.triangles_points_index[other_tri_i] = other_trii_new0
                                    self.enriched_mesh.triangles_points_index = np.vstack((self.enriched_mesh.triangles_points_index, other_trii_new1))

                                    self.has_edge_been_handled[j01_at] = p01_at_index

                                    self.enriched_mesh.n_tri = self.enriched_mesh.n_tri + 3
                                    self.enriched_mesh.n = self.enriched_mesh.n + 2
                                elif lambda_barycentric[np.where(trii == np.intersect1d(e01_ga, e01_at)[0])[0]] < self.delta: #then e_other is the edge triple point shifts to
                                    print('bend edge other')
                                    p01_at_index = self.enriched_mesh.n + 1
                                    self.enriched_mesh.points = np.vstack((self.enriched_mesh.points, p01_at))

                                    phi_ga_pe = self.level_set_gammaalpha_enriched.interpolate(trii, tri, p01_at)
                                    if phi_ga_pe < 0:
                                        self.has_point_been_shifted = np.vstack((self.has_point_been_shifted, [1, 3]))
                                    else:
                                        self.has_point_been_shifted = np.vstack((self.has_point_been_shifted, [1, 2]))
                                    self.level_set_gammaalpha_enriched.phi = np.hstack((self.level_set_gammaalpha_enriched.phi, phi_ga_pe))
                                    self.level_set_alphatheta_enriched.phi = np.hstack((self.level_set_alphatheta_enriched.phi, 0))

                                    cut_Tau = np.zeros(self.background_mesh.n+1)
                                    cut_Tau[[e01_at]] = np.array([1-taue01_at, taue01_at])
                                    if self.background_mesh.Tau[e01_at[0], e01_at[0]] != 0:
                                        other_points = self.background_mesh.Tau[e01_at[0]].nonzero()[1]
                                        cut_Tau[e01_at[0]] = 0
                                        cut_Tau[[other_points]] = cut_Tau[[other_points]] + (1-taue01_at) * self.background_mesh.Tau[e01_at[0], other_points].toarray()
                                    if self.background_mesh.Tau[e01_at[1], e01_at[1]] != 0:
                                        other_points = self.background_mesh.Tau[e01_at[1]].nonzero()[1]
                                        cut_Tau[e01_at[1]] = 0
                                        cut_Tau[[other_points]] = cut_Tau[[other_points]] + taue01_at * self.background_mesh.Tau[e01_at[1], other_points].toarray()
                                    cut_Tau[self.background_mesh.n] = p01_at_index
                                    self.background_mesh.Tau = vstack((self.background_mesh.Tau, cut_Tau), format = 'lil')

                                    p01_ga_index = self.enriched_mesh.n + 2
                                    self.enriched_mesh.points = np.vstack((self.enriched_mesh.points, p01_ga))
                                    phi_at_pe = self.level_set_alphatheta_enriched.interpolate(trii, tri, p01_ga)
                                    if phi_at_pe < 0:
                                        self.has_point_been_shifted = np.vstack((self.has_point_been_shifted, [1, 1]))
                                    else:
                                        self.has_point_been_shifted = np.vstack((self.has_point_been_shifted, [1, 11]))
                                    self.level_set_gammaalpha_enriched.phi = np.hstack((self.level_set_gammaalpha_enriched.phi, 0))
                                    self.level_set_alphatheta_enriched.phi = np.hstack((self.level_set_alphatheta_enriched.phi, phi_at_pe))

                                    cut_Tau = np.zeros(self.background_mesh.n+1)
                                    cut_Tau[[e01_ga]] = np.array([1-taue01_ga, taue01_ga])
                                    if self.background_mesh.Tau[e01_ga[0], e01_ga[0]] != 0:
                                        other_points = self.background_mesh.Tau[e01_ga[0]].nonzero()[1]
                                        cut_Tau[e01_ga[0]] = 0
                                        cut_Tau[[other_points]] = cut_Tau[[other_points]] + (1-taue01_ga) * self.background_mesh.Tau[e01_ga[0], other_points].toarray()
                                    if self.background_mesh.Tau[e01_ga[1], e01_ga[1]] != 0:
                                        other_points = self.background_mesh.Tau[e01_ga[1]].nonzero()[1]
                                        cut_Tau[e01_ga[1]] = 0
                                        cut_Tau[[other_points]] = cut_Tau[[other_points]] + taue01_ga * self.background_mesh.Tau[e01_ga[1], other_points].toarray()
                                    cut_Tau[self.background_mesh.n] = p01_ga_index
                                    self.background_mesh.Tau = vstack((self.background_mesh.Tau, cut_Tau), format = 'lil')

                                    trii0, trii1 = cGrid.least_angle_trii(self, np.intersect1d(e01_at, e01_ga)[0], p01_at_index, p01_ga_index, x_ga_index)
                                    trii2 = np.hstack((p11_ga_index, p01_at_index, x_ga_index))
                                    trii3 = np.hstack((p11_at_index, p01_ga_index, x_ga_index))

                                    self.enriched_mesh.triangles_points_index[i] = trii0
                                    self.enriched_mesh.triangles_points_index = np.vstack((self.enriched_mesh.triangles_points_index, trii1, trii2, trii3))

                                    e_other = np.sort([p11_ga_index, p11_at_index])
                                    j_other = self.enriched_mesh.edge_to_index[e_other[0],e_other[1]]

                                    other_tri_i = np.setdiff1d(self.background_mesh.edge_in_tri[j_other], i)[0]
                                    other_trii = self.background_mesh.triangles_points_index[other_tri_i]
                                    other_trii_new0, other_trii_new1 = cGrid.least_angle_trii(self, e_other[0], np.setdiff1d(other_trii, e_other)[0], x_ga_index, e_other[1])

                                    self.enriched_mesh.triangles_points_index[other_tri_i] = other_trii_new0
                                    self.enriched_mesh.triangles_points_index = np.vstack((self.enriched_mesh.triangles_points_index, other_trii_new1))

                                    self.has_edge_been_handled[j01_ga] = p01_ga_index
                                    self.has_edge_been_handled[j01_at] = p01_at_index

                                    self.enriched_mesh.n_tri = self.enriched_mesh.n_tri + 4
                                    self.enriched_mesh.n = self.enriched_mesh.n + 3

                            elif ga == 1 and at == 2: #bend 012
                                x_ga_index     = self.enriched_mesh.n + 0
                                p1_other_index = self.enriched_mesh.n + 1
                                if lambda_barycentric[np.where(trii == np.intersect1d(e01_at, e01_ga)[0])[0]] > self.delta: #then e01_at is the edge triple point shifts to
                                    p1_shift = p01_at
                                    e1_shift = e01_at
                                    j1_shift = j01_at
                                    p1_other = p11_at
                                    e1_other = e11_at
                                    j1_other = j11_at
                                    taue1_other = taue11_at
                                else:
                                    p1_shift = p11_at
                                    e1_shift = e11_at
                                    j1_shift = j11_at
                                    p1_other = p01_at
                                    e1_other = e01_at
                                    j1_other = j01_at
                                    taue1_other = taue01_at

                                self.enriched_mesh.points = np.vstack((self.enriched_mesh.points, x_ga, p1_other))

                                phi_ga_pe = self.level_set_gammaalpha_enriched.interpolate(trii, tri, p1_other)
                                if phi_ga_pe < 0:
                                    self.has_point_been_shifted = np.vstack((self.has_point_been_shifted, [1, 12], [1, 3]))
                                else:
                                    self.has_point_been_shifted = np.vstack((self.has_point_been_shifted, [1, 12], [1, 2]))
                                self.level_set_gammaalpha_enriched.phi = np.hstack((self.level_set_gammaalpha_enriched.phi, 0, phi_ga_pe))
                                self.level_set_alphatheta_enriched.phi = np.hstack((self.level_set_alphatheta_enriched.phi, np.zeros(2)))

                                cut_Tau = np.zeros(self.background_mesh.n+1)
                                cut_Tau[[e1_other]] = np.array([1-taue1_other, taue1_other])
                                if self.background_mesh.Tau[e1_other[0], e1_other[0]] != 0:
                                    other_points = self.background_mesh.Tau[e1_other[0]].nonzero()[1]
                                    cut_Tau[e1_other[0]] = 0
                                    cut_Tau[[other_points]] = cut_Tau[[other_points]] + (1-taue1_other) * self.background_mesh.Tau[e1_other[0], other_points].toarray()
                                if self.background_mesh.Tau[e1_other[1], e1_other[1]] != 0:
                                    other_points = self.background_mesh.Tau[e1_other[1]].nonzero()[1]
                                    cut_Tau[e1_other[1]] = 0
                                    cut_Tau[[other_points]] = cut_Tau[[other_points]] + taue1_other * self.background_mesh.Tau[e1_other[1], other_points].toarray()
                                cut_Tau[self.background_mesh.n] = p1_other_index
                                self.background_mesh.Tau = vstack((self.background_mesh.Tau, cut_Tau), format = 'lil')

                                p01_ga_index = self.enriched_mesh.n + 2
                                self.enriched_mesh.points = np.vstack((self.enriched_mesh.points, p01_ga))
                                phi_at_pe = self.level_set_alphatheta_enriched.interpolate(trii, tri, p01_ga)
                                if phi_at_pe < 0:
                                    self.has_point_been_shifted = np.vstack((self.has_point_been_shifted, [1, 1]))
                                else:
                                    self.has_point_been_shifted = np.vstack((self.has_point_been_shifted, [1, 11]))
                                self.level_set_gammaalpha_enriched.phi = np.hstack((self.level_set_gammaalpha_enriched.phi, 0))
                                self.level_set_alphatheta_enriched.phi = np.hstack((self.level_set_alphatheta_enriched.phi, phi_at_pe))

                                cut_Tau = np.zeros(self.background_mesh.n+1)
                                cut_Tau[[e01_ga]] = np.array([1-taue01_ga, taue01_ga])
                                if self.background_mesh.Tau[e01_ga[0], e01_ga[0]] != 0:
                                    other_points = self.background_mesh.Tau[e01_ga[0]].nonzero()[1]
                                    cut_Tau[e01_ga[0]] = 0
                                    cut_Tau[[other_points]] = cut_Tau[[other_points]] + (1-taue01_ga) * self.background_mesh.Tau[e01_ga[0], other_points].toarray()
                                if self.background_mesh.Tau[e01_ga[1], e01_ga[1]] != 0:
                                    other_points = self.background_mesh.Tau[e01_ga[1]].nonzero()[1]
                                    cut_Tau[e01_ga[1]] = 0
                                    cut_Tau[[other_points]] = cut_Tau[[other_points]] + taue01_ga * self.background_mesh.Tau[e01_ga[1], other_points].toarray()
                                cut_Tau[self.background_mesh.n] = p01_ga_index
                                self.background_mesh.Tau = vstack((self.background_mesh.Tau, cut_Tau), format = 'lil')

                                trii0, trii1 = cGrid.least_angle_trii(self, np.intersect1d(e1_other, e01_ga)[0], p01_ga_index, p1_other_index, x_ga_index)
                                trii2 = np.hstack((p11_ga_index, p1_other_index, x_ga_index))
                                trii3 = np.hstack((np.intersect1d(e01_ga, e1_shift)[0], p01_ga_index, x_ga_index))

                                self.enriched_mesh.triangles_points_index[i] = trii2
                                self.enriched_mesh.triangles_points_index = np.vstack((self.enriched_mesh.triangles_points_index, trii0, trii1, trii3))

                                other_tri_i = np.setdiff1d(self.background_mesh.edge_in_tri[j1_shift], i)[0]
                                other_trii = self.background_mesh.triangles_points_index[other_tri_i]
                                other_trii_new0, other_trii_new1 = cGrid.least_angle_trii(self, e1_shift[0], np.setdiff1d(other_trii, e1_shift)[0], x_ga_index, e1_shift[1])

                                self.enriched_mesh.triangles_points_index[other_tri_i] = other_trii_new0
                                self.enriched_mesh.triangles_points_index = np.vstack((self.enriched_mesh.triangles_points_index, other_trii_new1))

                                self.has_edge_been_handled[j1_other] = p1_other_index
                                self.has_edge_been_handled[j01_ga] = p01_ga_index

                                self.enriched_mesh.n_tri = self.enriched_mesh.n_tri + 4
                                self.enriched_mesh.n = self.enriched_mesh.n + 3
                            elif ga == 2 and at == 1: #bend 021
                                x_ga_index   = self.enriched_mesh.n + 0
                                p01_at_index = self.enriched_mesh.n + 1
                                p1_other_index = self.enriched_mesh.n + 2
                                self.enriched_mesh.points = np.vstack((self.enriched_mesh.points, x_ga, p01_at))

                                phi_ga_pe = self.level_set_gammaalpha_enriched.interpolate(trii, tri, p01_at)
                                if phi_ga_pe < 0:
                                    self.has_point_been_shifted = np.vstack((self.has_point_been_shifted, [1, 12], [1, 3]))
                                else:
                                    self.has_point_been_shifted = np.vstack((self.has_point_been_shifted, [1, 12], [1, 2]))
                                self.level_set_gammaalpha_enriched.phi = np.hstack((self.level_set_gammaalpha_enriched.phi, 0, phi_ga_pe))
                                self.level_set_alphatheta_enriched.phi = np.hstack((self.level_set_alphatheta_enriched.phi, np.zeros(2)))

                                cut_Tau = np.zeros(self.background_mesh.n+1)
                                cut_Tau[[e01_at]] = np.array([1-taue01_at, taue01_at])
                                if self.background_mesh.Tau[e01_at[0], e01_at[0]] != 0:
                                    other_points = self.background_mesh.Tau[e01_at[0]].nonzero()[1]
                                    cut_Tau[e01_at[0]] = 0
                                    cut_Tau[[other_points]] = cut_Tau[[other_points]] + (1-taue01_at) * self.background_mesh.Tau[e01_at[0], other_points].toarray()
                                if self.background_mesh.Tau[e01_at[1], e01_at[1]] != 0:
                                    other_points = self.background_mesh.Tau[e01_at[1]].nonzero()[1]
                                    cut_Tau[e01_at[1]] = 0
                                    cut_Tau[[other_points]] = cut_Tau[[other_points]] + taue01_at * self.background_mesh.Tau[e01_at[1], other_points].toarray()
                                cut_Tau[self.background_mesh.n] = p01_at_index
                                self.background_mesh.Tau = vstack((self.background_mesh.Tau, cut_Tau), format = 'lil')

                                if lambda_barycentric[np.where(trii == np.intersect1d(e11_ga, e01_at)[0])[0]] < self.delta: #then e01_ga is the edge triple point shifts to
                                    p1_shift = p01_ga
                                    e1_shift = e01_ga
                                    j1_shift = j01_ga
                                    p1_other = p11_ga
                                    e1_other = e11_ga
                                    j1_other = j11_ga
                                    taue1_other = taue11_ga
                                elif lambda_barycentric[np.where(trii == np.intersect1d(e01_ga, e01_at)[0])[0]] < self.delta: #then e11_ga is the edge triple point shifts to
                                    p1_shift = p11_ga
                                    e1_shift = e11_ga
                                    j1_shift = j11_ga
                                    p1_other = p01_ga
                                    e1_other = e01_ga
                                    j1_other = j01_ga
                                    taue1_other = taue01_ga
                                else:
                                    print('bend 021 to p01at edge, not really possible. especially with numerical inaccuracy. both ga points have exactly tau = delta.')

                                self.enriched_mesh.points = np.vstack((self.enriched_mesh.points, p1_other))
                                phi_at_pe = self.level_set_alphatheta_enriched.interpolate(trii, tri, p1_other)
                                if phi_at_pe < 0:
                                    self.has_point_been_shifted = np.vstack((self.has_point_been_shifted, [1, 1]))
                                else:
                                    self.has_point_been_shifted = np.vstack((self.has_point_been_shifted, [1, 11]))
                                self.level_set_gammaalpha_enriched.phi = np.hstack((self.level_set_gammaalpha_enriched.phi, 0))
                                self.level_set_alphatheta_enriched.phi = np.hstack((self.level_set_alphatheta_enriched.phi, phi_at_pe))

                                cut_Tau = np.zeros(self.background_mesh.n+1)
                                cut_Tau[[e1_other]] = np.array([1-taue1_other, taue1_other])
                                if self.background_mesh.Tau[e1_other[0], e1_other[0]] != 0:
                                    other_points = self.background_mesh.Tau[e1_other[0]].nonzero()[1]
                                    cut_Tau[e1_other[0]] = 0
                                    cut_Tau[[other_points]] = cut_Tau[[other_points]] + (1-taue1_other) * self.background_mesh.Tau[e1_other[0], other_points].toarray()
                                if self.background_mesh.Tau[e1_other[1], e1_other[1]] != 0:
                                    other_points = self.background_mesh.Tau[e1_other[1]].nonzero()[1]
                                    cut_Tau[e1_other[1]] = 0
                                    cut_Tau[[other_points]] = cut_Tau[[other_points]] + taue1_other * self.background_mesh.Tau[e1_other[1], other_points].toarray()
                                cut_Tau[self.background_mesh.n] = p1_other_index
                                self.background_mesh.Tau = vstack((self.background_mesh.Tau, cut_Tau), format = 'lil')

                                trii0, trii1 = cGrid.least_angle_trii(self, np.intersect1d(e01_at, e1_other)[0], p1_other_index, p01_at_index, x_ga_index)
                                trii2 = np.hstack((np.setdiff1d(e01_at, e1_other)[0], p01_at_index, x_ga_index))
                                trii3 = np.hstack((p11_at_index, p1_other_index, x_ga_index))

                                self.enriched_mesh.triangles_points_index[i] = trii3
                                self.enriched_mesh.triangles_points_index = np.vstack((self.enriched_mesh.triangles_points_index, trii0, trii1, trii2))

                                other_tri_i = np.setdiff1d(self.background_mesh.edge_in_tri[j1_shift], i)[0]
                                other_trii = self.background_mesh.triangles_points_index[other_tri_i]
                                other_trii_new0, other_trii_new1 = cGrid.least_angle_trii(self, e1_shift[0], np.setdiff1d(other_trii, e1_shift)[0], x_ga_index, e1_shift[1])

                                self.enriched_mesh.triangles_points_index[other_tri_i] = other_trii_new0
                                self.enriched_mesh.triangles_points_index = np.vstack((self.enriched_mesh.triangles_points_index, other_trii_new1))

                                self.has_edge_been_handled[j1_other] = p1_other_index
                                self.has_edge_been_handled[j01_at] = p01_at_index

                                self.enriched_mesh.n_tri = self.enriched_mesh.n_tri + 4
                                self.enriched_mesh.n = self.enriched_mesh.n + 3
                            #When the triple point is on an edge of an interface
                            elif ga + at == 1:
                                if ga == 1: #bend 010
                                    #Test if triple point is indeed on edge
                                    if la.norm(x_ga - p01_ga) > 1e-13:
                                        print('triple point should be on edge e01_ga but isnt x_ga, p01_ga', x_ga, p01_ga, 't ', t, np.sort(t) == np.array([0,1]))
                                    x_ga_index = self.enriched_mesh.n + 0
                                    if self.has_edge_been_handled[j01_ga,0] == -1:
                                        self.enriched_mesh.points = np.vstack((self.enriched_mesh.points, x_ga))
                                        self.has_point_been_shifted = np.vstack((self.has_point_been_shifted, [1, 12]))
                                        self.level_set_gammaalpha_enriched.phi = np.hstack((self.level_set_gammaalpha_enriched.phi, 0))
                                        self.level_set_alphatheta_enriched.phi = np.hstack((self.level_set_alphatheta_enriched.phi, 0))

                                        trii0 = np.hstack((p11_ga_index, e01_ga[0], x_ga_index))
                                        trii1 = np.hstack((p11_ga_index, e01_ga[1], x_ga_index))

                                        self.enriched_mesh.triangles_points_index[i] = trii0
                                        self.enriched_mesh.triangles_points_index = np.vstack((self.enriched_mesh.triangles_points_index, trii1))

                                        other_tri_i = np.setdiff1d(self.background_mesh.edge_in_tri[j01_ga], i)[0]
                                        other_trii = self.background_mesh.triangles_points_index[other_tri_i]
                                        #triple point is on edge, so only one way to split other triangle
                                        other_trii_new0 = np.hstack((e01_ga[0], np.setdiff1d(other_trii, e01_ga)[0], x_ga_index))
                                        other_trii_new1 = np.hstack((e01_ga[1], np.setdiff1d(other_trii, e01_ga)[0], x_ga_index))

                                        self.enriched_mesh.triangles_points_index[other_tri_i] = other_trii_new0
                                        self.enriched_mesh.triangles_points_index = np.vstack((self.enriched_mesh.triangles_points_index, other_trii_new1))

                                        self.enriched_mesh.n_tri = self.enriched_mesh.n_tri + 2
                                        self.enriched_mesh.n = self.enriched_mesh.n + 1
                                    else:
                                        print('edge j01_ga ', j01_ga, 'already cut')
                                        not_triple == True
                                else: #bend 001
                                    if la.norm(x_ga - p01_at) > 1e-13:
                                        print('triple point should be on edge e01_at but isnt x_at, p01_at', x_ga, p01_at)
                                    if self.has_edge_been_handled[j01_at,1] == -1:
                                        x_ga_index = self.enriched_mesh.n + 0
                                        self.enriched_mesh.points = np.vstack((self.enriched_mesh.points, x_ga))
                                        self.has_point_been_shifted = np.vstack((self.has_point_been_shifted, [1, 12]))
                                        self.level_set_gammaalpha_enriched.phi = np.hstack((self.level_set_gammaalpha_enriched.phi, 0))
                                        self.level_set_alphatheta_enriched.phi = np.hstack((self.level_set_alphatheta_enriched.phi, 0))

                                        trii0 = np.hstack((p11_at_index, e01_at[0], x_ga_index))
                                        trii1 = np.hstack((p11_at_index, e01_at[1], x_ga_index))

                                        self.enriched_mesh.triangles_points_index[i] = trii0
                                        self.enriched_mesh.triangles_points_index = np.vstack((self.enriched_mesh.triangles_points_index, trii1))

                                        other_tri_i = np.setdiff1d(self.background_mesh.edge_in_tri[j01_at], i)[0]
                                        other_trii = self.background_mesh.triangles_points_index[other_tri_i]
                                        #triple point is on edge, so only one way to split other triangle
                                        other_trii_new0 = np.hstack((e01_at[0], np.setdiff1d(other_trii, e01_at)[0], x_ga_index))
                                        other_trii_new1 = np.hstack((e01_at[1], np.setdiff1d(other_trii, e01_at)[0], x_ga_index))

                                        self.enriched_mesh.triangles_points_index[other_tri_i] = other_trii_new0
                                        self.enriched_mesh.triangles_points_index = np.vstack((self.enriched_mesh.triangles_points_index, other_trii_new1))

                                        self.enriched_mesh.n_tri = self.enriched_mesh.n_tri + 2
                                        self.enriched_mesh.n = self.enriched_mesh.n + 1
                                    else:
                                        print('edge j01_at ', j01_at, 'already cut')
                                        not_triple = True

                            elif ga == 2 and at == 0: #bend 020
                                p1_shift_index = self.enriched_mesh.n + 0 #shift = x_ga
                                x_ga_index = p1_shift_index
                                p1_other_index = self.enriched_mesh.n + 1
                                if la.norm(x_ga - p01_ga) < 1e-13:
                                    p1_shift = p01_ga
                                    e1_shift = e01_ga
                                    j1_shift = j01_ga
                                    p1_other = p11_ga
                                    e1_other = e11_ga
                                    j1_other = j11_ga
                                    taue1_other = taue11_ga
                                elif la.norm(x_ga - p11_ga) < 1e-13:
                                    p1_shift = p11_ga
                                    e1_shift = e11_ga
                                    j1_shift = j11_ga
                                    p1_other = p01_ga
                                    e1_other = e01_ga
                                    j1_other = j01_ga
                                    taue1_other = taue01_ga
                                else:
                                    print('p_ga = x_ga should be cutting p_at edge p01_ga, p11_ga x_ga ', p01_ga, p11_ga, x_ga)
                                if self.has_edge_been_handled[j1_shift,0] == -1:
                                    self.enriched_mesh.points = np.vstack((self.enriched_mesh.points, p1_shift, p1_other)) #shift = ga
                                    phi_at_p1_other = self.level_set_alphatheta_enriched.interpolate(trii, tri, p1_other)
                                    if phi_at_p1_other < 0:
                                        self.has_point_been_shifted = np.vstack((self.has_point_been_shifted, [1, 12], [1, 1]))
                                    elif phi_at_p1_other > 0:
                                        self.has_point_been_shifted = np.vstack((self.has_point_been_shifted, [1, 12], [1, 11]))
                                    else:
                                        print('p1_other triple point???')
                                    self.level_set_gammaalpha_enriched.phi = np.hstack((self.level_set_gammaalpha_enriched.phi, np.zeros(2)))
                                    self.level_set_alphatheta_enriched.phi = np.hstack((self.level_set_alphatheta_enriched.phi, 0, phi_at_p1_other))

                                    cut_Tau = np.zeros(self.background_mesh.n+1)
                                    cut_Tau[[e1_other]] = np.array([1-taue1_other, taue1_other])
                                    if self.background_mesh.Tau[e1_other[0], e1_other[0]] != 0:
                                        other_points = self.background_mesh.Tau[e1_other[0]].nonzero()[1]
                                        cut_Tau[e1_other[0]] = 0
                                        cut_Tau[[other_points]] = cut_Tau[[other_points]] + (1-taue1_other) * self.background_mesh.Tau[e1_other[0], other_points].toarray()
                                    if self.background_mesh.Tau[e1_other[1], e1_other[1]] != 0:
                                        other_points = self.background_mesh.Tau[e1_other[1]].nonzero()[1]
                                        cut_Tau[e1_other[1]] = 0
                                        cut_Tau[[other_points]] = cut_Tau[[other_points]] + taue1_other * self.background_mesh.Tau[e1_other[1], other_points].toarray()
                                    cut_Tau[self.background_mesh.n] = p1_other_index
                                    self.background_mesh.Tau = vstack((self.background_mesh.Tau, cut_Tau), format = 'lil')

                                    trii0, trii1 = cGrid.least_angle_trii(self, np.setdiff1d(e1_shift, e1_other)[0], np.setdiff1d(e1_other, e1_shift)[0], p1_shift_index, p1_other_index)
                                    trii2 = np.hstack((np.intersect1d(e1_shift, e1_other)[0], p1_other_index, p1_shift_index))

                                    self.enriched_mesh.triangles_points_index[i] = trii0
                                    self.enriched_mesh.triangles_points_index = np.vstack((self.enriched_mesh.triangles_points_index, trii1, trii2))

                                    other_tri_i = np.setdiff1d(self.background_mesh.edge_in_tri[j1_shift], i)[0]
                                    other_trii = self.background_mesh.triangles_points_index[other_tri_i]
                                    #triple point is on edge, so only one way to split other triangle
                                    other_trii_new0 = np.hstack((e1_shift[0], np.setdiff1d(other_trii, e1_shift)[0], p1_shift_index))
                                    other_trii_new1 = np.hstack((e1_shift[1], np.setdiff1d(other_trii, e1_shift)[0], p1_shift_index))

                                    self.enriched_mesh.triangles_points_index[other_tri_i] = other_trii_new0
                                    self.enriched_mesh.triangles_points_index = np.vstack((self.enriched_mesh.triangles_points_index, other_trii_new1))

                                    self.has_edge_been_handled[j1_other] = p1_other_index

                                    self.enriched_mesh.n_tri = self.enriched_mesh.n_tri + 3
                                    self.enriched_mesh.n = self.enriched_mesh.n + 2
                                else:
                                    print('edge j1_shift ', j1_shift, 'already cut')
                                    not_triple = True
                            elif ga == 0 and at == 2: #bend 002
                                p1_shift_index = self.enriched_mesh.n + 0 #shift = x_ga
                                x_ga_index = p1_shift_index
                                p1_other_index = self.enriched_mesh.n + 1
                                if la.norm(x_ga - p01_at) < 1e-13:
                                    p1_shift = p01_at
                                    e1_shift = e01_at
                                    j1_shift = j01_at
                                    p1_other = p11_at
                                    e1_other = e11_at
                                    j1_other = j11_at
                                    taue1_other = taue11_at
                                elif la.norm(x_ga - p11_at) < 1e-13:
                                    p1_shift = p11_at
                                    e1_shift = e11_at
                                    j1_shift = j11_at
                                    p1_other = p01_at
                                    e1_other = e01_at
                                    j1_other = j01_at
                                    taue1_other = taue01_at
                                else:
                                    print('p_ga = x_at should be cutting p_ga edge p01_at, p11_at x_ga ', p01_at, p11_at, x_ga)

                                if self.has_edge_been_handled[j1_shift,1] == -1:
                                    self.enriched_mesh.points = np.vstack((self.enriched_mesh.points, p1_shift, p1_other))

                                    phi_ga_pe = self.level_set_gammaalpha_enriched.interpolate(trii, tri, p1_other)
                                    if phi_ga_pe < 0:
                                        self.has_point_been_shifted = np.vstack((self.has_point_been_shifted, [1, 12], [1, 3]))
                                    else:
                                        self.has_point_been_shifted = np.vstack((self.has_point_been_shifted, [1, 12], [1, 2]))
                                    self.level_set_gammaalpha_enriched.phi = np.hstack((self.level_set_gammaalpha_enriched.phi, 0, phi_ga_pe))
                                    self.level_set_alphatheta_enriched.phi = np.hstack((self.level_set_alphatheta_enriched.phi, np.zeros(2)))

                                    cut_Tau = np.zeros(self.background_mesh.n+1)
                                    cut_Tau[[e1_other]] = np.array([1-taue1_other, taue1_other])
                                    if self.background_mesh.Tau[e1_other[0], e1_other[0]] != 0:
                                        other_points = self.background_mesh.Tau[e1_other[0]].nonzero()[1]
                                        cut_Tau[e1_other[0]] = 0
                                        cut_Tau[[other_points]] = cut_Tau[[other_points]] + (1-taue1_other) * self.background_mesh.Tau[e1_other[0], other_points].toarray()
                                    if self.background_mesh.Tau[e1_other[1], e1_other[1]] != 0:
                                        other_points = self.background_mesh.Tau[e1_other[1]].nonzero()[1]
                                        cut_Tau[e1_other[1]] = 0
                                        cut_Tau[[other_points]] = cut_Tau[[other_points]] + taue1_other * self.background_mesh.Tau[e1_other[1], other_points].toarray()
                                    cut_Tau[self.background_mesh.n] = p1_other_index
                                    self.background_mesh.Tau = vstack((self.background_mesh.Tau, cut_Tau), format = 'lil')

                                    trii0, trii1 = cGrid.least_angle_trii(self, np.setdiff1d(e1_shift, e1_other)[0], np.setdiff1d(e1_other, e1_shift)[0], p1_shift_index, p1_other_index)
                                    trii2 = np.hstack((np.intersect1d(e1_shift, e1_other)[0], p1_other_index, p1_shift_index))

                                    self.enriched_mesh.triangles_points_index[i] = trii0
                                    self.enriched_mesh.triangles_points_index = np.vstack((self.enriched_mesh.triangles_points_index, trii1, trii2))

                                    other_tri_i = np.setdiff1d(self.background_mesh.edge_in_tri[j1_shift], i)[0]
                                    other_trii = self.background_mesh.triangles_points_index[other_tri_i]
                                    #triple point is on edge, so only one way to split other triangle
                                    other_trii_new0 = np.hstack((e1_shift[0], np.setdiff1d(other_trii, e1_shift)[0], p1_shift_index))
                                    other_trii_new1 = np.hstack((e1_shift[1], np.setdiff1d(other_trii, e1_shift)[0], p1_shift_index))

                                    self.enriched_mesh.triangles_points_index[other_tri_i] = other_trii_new0
                                    self.enriched_mesh.triangles_points_index = np.vstack((self.enriched_mesh.triangles_points_index, other_trii_new1))

                                    self.has_edge_been_handled[j1_other] = p1_other_index

                                    self.enriched_mesh.n_tri = self.enriched_mesh.n_tri + 3
                                    self.enriched_mesh.n = self.enriched_mesh.n + 2
                                else:
                                    print('edge j1_shift ', j1_shift, 'already cut')
                                    not_triple = True
                            elif ga == 0 and at == 1: #bend 001
                                if la.norm(x_ga - p01_at) > 1e-13:
                                     print('triple point shoulf be p01_at, but isnt. p01_at x_ga ', p01_at, x_ga)
                                if self.has_edge_been_handled[j01_at,1] == -1:
                                    p01_at_index = self.enriched_mesh.n + 0 # = x_ga
                                    x_ga_index = p01_at_index
                                    self.enriched_mesh.points = np.vstack((self.enriched_mesh.points, p01_at))
                                    self.has_point_been_shifted = np.vstack((self.has_point_been_shifted, [1, 12]))
                                    self.level_set_gammaalpha_enriched.phi = np.hstack((self.level_set_gammaalpha_enriched.phi, 0))
                                    self.level_set_alphatheta_enriched.phi = np.hstack((self.level_set_alphatheta_enriched.phi, 0))

                                    trii0 = np.hstack((p01_ga_index, p11_at_index, p01_at_index))
                                    trii1 = np.hstack((p11_ga_index, p11_at_index, p01_at_index))

                                    self.enriched_mesh.triangles_points_index[i] = trii0
                                    self.enriched_mesh.triangles_points_index = np.vstack((self.enriched_mesh.triangles_points_index, trii1))

                                    other_tri_i = np.setdiff1d(self.background_mesh.edge_in_tri[j01_at], i)[0]
                                    other_trii = self.background_mesh.triangles_points_index[other_tri_i]
                                    #triple point is on edge, so only one way to split other triangle
                                    other_trii_new0 = np.hstack((e01_at[0], np.setdiff1d(other_trii, e01_at)[0], p01_at_index))
                                    other_trii_new1 = np.hstack((e01_at[1], np.setdiff1d(other_trii, e01_at)[0], p01_at_index))

                                    self.enriched_mesh.triangles_points_index[other_tri_i] = other_trii_new0
                                    self.enriched_mesh.triangles_points_index = np.vstack((self.enriched_mesh.triangles_points_index, other_trii_new1))

                                    self.enriched_mesh.n_tri = self.enriched_mesh.n_tri + 2
                                    self.enriched_mesh.n = self.enriched_mesh.n + 1
                                else:
                                    print('edge j01_at ', j01_at, 'already cut')
                                    not_triple = True
#                                    self.interface_alphatheta.edges_index = np.vstack((self.interface_alphatheta.edges_index, np.sort([p11_at_index, p01_at_index])))
                        if not(not_triple):
                            self.triple_points_index = np.hstack((self.triple_points_index, x_ga_index))
                        else:
                            def delete_row_lil(mat, i):
                                if not isinstance(mat, lil_matrix):
                                    raise ValueError("works only for LIL format -- use .tolil() first")
                                mat.rows = np.delete(mat.rows, i)
                                mat.data = np.delete(mat.data, i)
                                mat._shape = (mat._shape[0] - 1, mat._shape[1])
                            delete_row_lil(self.background_mesh.Tau, -1)
                    #else 'cut', have to take into account corners can be interface points
#                        elif where_lambda_big.shape[0] == 0 or self.has_point_been_shifted[trii[where_lambda_big][0],0] == 1 and not(self.has_point_been_shifted[trii[where_lambda_big][0],1]%4 == 0):
                    elif where_lambda_smaller_other_delta.shape[0] == 0:
                        triple_Tau0 = np.zeros(self.background_mesh.n+1)
                        triple_Tau1 = np.zeros(self.background_mesh.n+1)
                        triple_Tau2 = np.zeros(self.background_mesh.n+1)
                        triple_Tau0[trii[0]] = lambda_barycentric[0]
                        triple_Tau1[trii[1]] = lambda_barycentric[1]
                        triple_Tau2[trii[2]] = lambda_barycentric[2]
                        if self.background_mesh.Tau[trii[0], trii[0]] != 0:
                            other_points = self.background_mesh.Tau[trii[0]].nonzero()[1]
                            triple_Tau0[trii[0]] = 0
                            triple_Tau0[[other_points]] = lambda_barycentric[0] * self.background_mesh.Tau[trii[0], other_points].toarray()
                        if self.background_mesh.Tau[trii[1], trii[1]] != 0:
                            other_points = self.background_mesh.Tau[trii[1]].nonzero()[1]
                            triple_Tau1[trii[1]] = 0
                            triple_Tau1[[other_points]] = lambda_barycentric[1] * self.background_mesh.Tau[trii[1], other_points].toarray()
                        if self.background_mesh.Tau[trii[2], trii[2]] != 0:
                            other_points = self.background_mesh.Tau[trii[2]].nonzero()[1]
                            triple_Tau2[trii[2]] = 0
                            triple_Tau2[[other_points]] = lambda_barycentric[2] * self.background_mesh.Tau[trii[2], other_points].toarray()
                        triple_Tau = triple_Tau0 + triple_Tau1 + triple_Tau2
                        triple_Tau[self.background_mesh.n] = self.enriched_mesh.n
                        self.background_mesh.Tau = vstack((self.background_mesh.Tau, triple_Tau), format = 'lil')
                        print('cut, ga_at, ga, at', ga_at, ga, at, x_ga)
                        #both interfaces go through one similar edge
                        if ga_at == 1:
                            if ga == 1 and at == 1: #cut 111
                                x_ga_index   = self.enriched_mesh.n + 0
                                p01_ga_index = self.enriched_mesh.n + 1
                                p02_ga_index = self.enriched_mesh.n + 2
                                p02_at_index = self.enriched_mesh.n + 3
                                p01_at_index = self.enriched_mesh.n + 4
                                self.enriched_mesh.points = np.vstack((self.enriched_mesh.points, x_ga, p01_ga, p02_ga, p02_at, p01_at))

                                phi_at_pe01 = self.level_set_alphatheta_enriched.interpolate(trii, tri, p01_ga)
                                phi_at_pe02 = self.level_set_alphatheta_enriched.interpolate(trii, tri, p02_ga)
                                if phi_at_pe01 < 0:
                                    self.has_point_been_shifted = np.vstack((self.has_point_been_shifted, [1, 1], [1, 11]))
                                else:
                                    self.has_point_been_shifted = np.vstack((self.has_point_been_shifted, [1, 11], [1, 1]))
                                if phi_at_pe01 * phi_at_pe02 > 0:
                                    print('p01_ga and p02_ga same sign for phi_at (theta) trii, tri, i', trii, tri, i)

                                phi_ga_pe02 = self.level_set_gammaalpha_enriched.interpolate(trii, tri, p02_at)
                                phi_ga_pe01 = self.level_set_gammaalpha_enriched.interpolate(trii, tri, p01_at)
                                if phi_ga_pe02 < 0:
                                    self.has_point_been_shifted = np.vstack((self.has_point_been_shifted, [1, 3]))
                                else:
                                    self.has_point_been_shifted = np.vstack((self.has_point_been_shifted, [1, 2]))
                                if phi_ga_pe01 < 0:
                                    self.has_point_been_shifted = np.vstack((self.has_point_been_shifted, [1, 3], [1, 4]))
                                else:
                                    self.has_point_been_shifted = np.vstack((self.has_point_been_shifted, [1, 2], [1, 4]))

                                self.level_set_gammaalpha_enriched.phi = np.hstack((self.level_set_gammaalpha_enriched.phi, 0, 0, 0, phi_ga_pe02, phi_ga_pe01))
                                self.level_set_alphatheta_enriched.phi = np.hstack((self.level_set_alphatheta_enriched.phi, 0,
                                                                                    phi_at_pe01,
                                                                                    phi_at_pe02,
                                                                                    np.zeros(2)))

                                cut_Tau = np.zeros(self.background_mesh.n+1)
                                cut_Tau[[e01_ga]] = np.array([1-taue01_ga, taue01_ga])
                                if self.background_mesh.Tau[e01_ga[0], e01_ga[0]] != 0:
                                    other_points = self.background_mesh.Tau[e01_ga[0]].nonzero()[1]
                                    cut_Tau[e01_ga[0]] = 0
                                    cut_Tau[[other_points]] = cut_Tau[[other_points]] + (1-taue01_ga) * self.background_mesh.Tau[e01_ga[0], other_points].toarray()
                                if self.background_mesh.Tau[e01_ga[1], e01_ga[1]] != 0:
                                    other_points = self.background_mesh.Tau[e01_ga[1]].nonzero()[1]
                                    cut_Tau[e01_ga[1]] = 0
                                    cut_Tau[[other_points]] = cut_Tau[[other_points]] + taue01_ga * self.background_mesh.Tau[e01_ga[1], other_points].toarray()
                                cut_Tau[self.background_mesh.n] = p01_ga_index
                                self.background_mesh.Tau = vstack((self.background_mesh.Tau, cut_Tau), format = 'lil')

                                cut_Tau = np.zeros(self.background_mesh.n+1)
                                cut_Tau[[e02]] = np.array([1-taue02_ga, taue02_ga])
                                if self.background_mesh.Tau[e02[0], e02[0]] != 0:
                                    other_points = self.background_mesh.Tau[e02[0]].nonzero()[1]
                                    cut_Tau[e02[0]] = 0
                                    cut_Tau[[other_points]] = cut_Tau[[other_points]] + (1-taue02_ga) * self.background_mesh.Tau[e02[0], other_points].toarray()
                                if self.background_mesh.Tau[e02[1], e02[1]] != 0:
                                    other_points = self.background_mesh.Tau[e02[1]].nonzero()[1]
                                    cut_Tau[e02[1]] = 0
                                    cut_Tau[[other_points]] = cut_Tau[[other_points]] + taue02_ga * self.background_mesh.Tau[e02[1], other_points].toarray()
                                cut_Tau[self.background_mesh.n] = p02_ga_index
                                self.background_mesh.Tau = vstack((self.background_mesh.Tau, cut_Tau), format = 'lil')

                                cut_Tau = np.zeros(self.background_mesh.n+1)
                                cut_Tau[[e01_at]] = np.array([1-taue01_at, taue01_at])
                                if self.background_mesh.Tau[e01_at[0], e01_at[0]] != 0:
                                    other_points = self.background_mesh.Tau[e01_at[0]].nonzero()[1]
                                    cut_Tau[e01_at[0]] = 0
                                    cut_Tau[[other_points]] = cut_Tau[[other_points]] + (1-taue01_at) * self.background_mesh.Tau[e01_at[0], other_points].toarray()
                                if self.background_mesh.Tau[e01_at[1], e01_at[1]] != 0:
                                    other_points = self.background_mesh.Tau[e01_at[1]].nonzero()[1]
                                    cut_Tau[e01_at[1]] = 0
                                    cut_Tau[[other_points]] = cut_Tau[[other_points]] + taue01_at * self.background_mesh.Tau[e01_at[1], other_points].toarray()
                                cut_Tau[self.background_mesh.n] = p01_at_index
                                self.background_mesh.Tau = vstack((self.background_mesh.Tau, cut_Tau), format = 'lil')

                                cut_Tau = np.zeros(self.background_mesh.n+1)
                                cut_Tau[[e02]] = np.array([1-taue02_at, taue02_at])
                                if self.background_mesh.Tau[e02[0], e02[0]] != 0:
                                    other_points = self.background_mesh.Tau[e02[0]].nonzero()[1]
                                    cut_Tau[e02[0]] = 0
                                    cut_Tau[[other_points]] = cut_Tau[[other_points]] + (1-taue02_at) * self.background_mesh.Tau[e02[0], other_points].toarray()
                                if self.background_mesh.Tau[e02[1], e02[1]] != 0:
                                    other_points = self.background_mesh.Tau[e02[1]].nonzero()[1]
                                    cut_Tau[e02[1]] = 0
                                    cut_Tau[[other_points]] = cut_Tau[[other_points]] + taue02_at * self.background_mesh.Tau[e02[1], other_points].toarray()
                                cut_Tau[self.background_mesh.n] = p02_at_index
                                self.background_mesh.Tau = vstack((self.background_mesh.Tau, cut_Tau), format = 'lil')

                                trii0, trii1 = cGrid.least_angle_trii(self, np.setdiff1d(e02, e01_at)[0], p01_ga_index, p02_at_index, x_ga_index)
                                trii2, trii3 = cGrid.least_angle_trii(self, np.setdiff1d(e01_at, e02)[0], p01_at_index, p01_ga_index, x_ga_index)
                                trii4, trii5 = cGrid.least_angle_trii(self, np.intersect1d(e01_at, e02)[0], p01_at_index, p02_ga_index, x_ga_index)
                                trii6 = np.hstack((p02_ga_index, p02_at_index, x_ga_index))


                                self.enriched_mesh.triangles_points_index[i] = trii4
                                self.enriched_mesh.triangles_points_index = np.vstack((self.enriched_mesh.triangles_points_index, trii0, trii1, trii2, trii3, trii5, trii6))
#
                                self.has_edge_been_handled[j02] = np.array([p02_ga_index, p02_at_index])
                                self.has_edge_been_handled[j01_ga] = p01_ga_index
                                self.has_edge_been_handled[j01_at] = p01_at_index
                                
                                self.enriched_mesh.n_tri = self.enriched_mesh.n_tri + 6
                                self.enriched_mesh.n = self.enriched_mesh.n + 5

                            elif ga == 0:
                                #ga through corner, at not
                                if at == 1: #cut 101
                                    x_ga_index   = self.enriched_mesh.n + 0
                                    p02_at_index = self.enriched_mesh.n + 1
                                    p01_at_index = self.enriched_mesh.n + 2
                                    p02_ga_index = self.enriched_mesh.n + 3
                                    self.enriched_mesh.points = np.vstack((self.enriched_mesh.points, x_ga, p02_at, p01_at, p02_ga))

                                    phi_ga_pe02 = self.level_set_gammaalpha_enriched.interpolate(trii, tri, p02_at)
                                    phi_ga_pe01 = self.level_set_gammaalpha_enriched.interpolate(trii, tri, p01_at)
                                    if phi_ga_pe02 < 0:
                                        self.has_point_been_shifted = np.vstack((self.has_point_been_shifted, [1, 4], [1, 3]))
                                    else:
                                        self.has_point_been_shifted = np.vstack((self.has_point_been_shifted, [1, 4], [1, 2]))
                                    if phi_ga_pe01 < 0:
                                        self.has_point_been_shifted = np.vstack((self.has_point_been_shifted, [1, 3]))
                                    else:
                                        self.has_point_been_shifted = np.vstack((self.has_point_been_shifted, [1, 2]))
                                    if phi_ga_pe02 * phi_ga_pe01 > 0:
                                        print('p02_at and p01_at same sign for phi_at (theta) trii, tri, i', trii, tri, i)
                                    phi_at_pe = self.level_set_alphatheta_enriched.interpolate(trii, tri, p02_ga)
                                    if phi_at_pe < 0:
                                        self.has_point_been_shifted = np.vstack((self.has_point_been_shifted, [1, 1]))
                                        if self.has_point_been_shifted[p01_ga_index, 1] == 1:
                                            print('p01_ga and p02_ga on same side of theta interface?')
                                    else:
                                        self.has_point_been_shifted = np.vstack((self.has_point_been_shifted, [1, 11]))
                                        if self.has_point_been_shifted[p01_ga_index, 1] == 11:
                                            print('p01_ga and p02_ga on same side of theta interface?')
                                    self.level_set_gammaalpha_enriched.phi = np.hstack((self.level_set_gammaalpha_enriched.phi, 0, phi_ga_pe02, phi_ga_pe01, 0))
                                    self.level_set_alphatheta_enriched.phi = np.hstack((self.level_set_alphatheta_enriched.phi, np.zeros(3), phi_at_pe))

                                    cut_Tau = np.zeros(self.background_mesh.n+1)
                                    cut_Tau[[e02]] = np.array([1-taue02_at, taue02_at])
                                    if self.background_mesh.Tau[e02[0], e02[0]] != 0:
                                        other_points = self.background_mesh.Tau[e02[0]].nonzero()[1]
                                        cut_Tau[e02[0]] = 0
                                        cut_Tau[[other_points]] = cut_Tau[[other_points]] + (1-taue02_at) * self.background_mesh.Tau[e02[0], other_points].toarray()
                                    if self.background_mesh.Tau[e02[1], e02[1]] != 0:
                                        other_points = self.background_mesh.Tau[e02[1]].nonzero()[1]
                                        cut_Tau[e02[1]] = 0
                                        cut_Tau[[other_points]] = cut_Tau[[other_points]] + taue02_at * self.background_mesh.Tau[e02[1], other_points].toarray()
                                    cut_Tau[self.background_mesh.n] = p02_at_index
                                    self.background_mesh.Tau = vstack((self.background_mesh.Tau, cut_Tau), format = 'lil')

                                    cut_Tau = np.zeros(self.background_mesh.n+1)
                                    cut_Tau[[e01_at]] = np.array([1-taue01_at, taue01_at])
                                    if self.background_mesh.Tau[e01_at[0], e01_at[0]] != 0:
                                        other_points = self.background_mesh.Tau[e01_at[0]].nonzero()[1]
                                        cut_Tau[e01_at[0]] = 0
                                        cut_Tau[[other_points]] = cut_Tau[[other_points]] + (1-taue01_at) * self.background_mesh.Tau[e01_at[0], other_points].toarray()
                                    if self.background_mesh.Tau[e01_at[1], e01_at[1]] != 0:
                                        other_points = self.background_mesh.Tau[e01_at[1]].nonzero()[1]
                                        cut_Tau[e01_at[1]] = 0
                                        cut_Tau[[other_points]] = cut_Tau[[other_points]] + taue01_at * self.background_mesh.Tau[e01_at[1], other_points].toarray()
                                    cut_Tau[self.background_mesh.n] = p01_at_index
                                    self.background_mesh.Tau = vstack((self.background_mesh.Tau, cut_Tau), format = 'lil')

                                    cut_Tau = np.zeros(self.background_mesh.n+1)
                                    cut_Tau[[e02]] = np.array([1-taue02_ga, taue02_ga])
                                    if self.background_mesh.Tau[e02[0], e02[0]] != 0:
                                        other_points = self.background_mesh.Tau[e02[0]].nonzero()[1]
                                        cut_Tau[e02[0]] = 0
                                        cut_Tau[[other_points]] = cut_Tau[[other_points]] + (1-taue02_ga) * self.background_mesh.Tau[e02[0], other_points].toarray()
                                    if self.background_mesh.Tau[e02[1], e02[1]] != 0:
                                        other_points = self.background_mesh.Tau[e02[1]].nonzero()[1]
                                        cut_Tau[e02[1]] = 0
                                        cut_Tau[[other_points]] = cut_Tau[[other_points]] + taue02_ga * self.background_mesh.Tau[e02[1], other_points].toarray()
                                    cut_Tau[self.background_mesh.n] = p02_ga_index
                                    self.background_mesh.Tau = vstack((self.background_mesh.Tau, cut_Tau), format = 'lil')

                                    trii0, trii1 = cGrid.least_angle_trii(self, p01_ga_index, x_ga_index, np.setdiff1d(e02, e01_at)[0], p02_at_index)
                                    trii2 = np.hstack((p01_ga_index, p01_at_index, x_ga_index))
                                    trii3, trii4 = cGrid.least_angle_trii(self,np.intersect1d(e02, e01_at)[0], p01_at_index, p02_ga_index, x_ga_index)
                                    trii5 = np.hstack((p02_ga_index, p02_at_index, x_ga_index))

                                    self.enriched_mesh.triangles_points_index[i] = trii4
                                    self.enriched_mesh.triangles_points_index = np.vstack((self.enriched_mesh.triangles_points_index, trii0, trii1, trii2, trii3, trii5))

                                    self.has_edge_been_handled[j02] = np.array([p02_ga_index, p02_at_index])
                                    self.has_edge_been_handled[j01_at] = p01_at_index

                                    self.enriched_mesh.n_tri = self.enriched_mesh.n_tri + 5
                                    self.enriched_mesh.n = self.enriched_mesh.n + 4
                                elif at == 0: #cut 100
                                    print('ga_at ga at = 1 0 0 not possible, cause triple point is in corner.')
                            elif at == 0:
                                #at through corner, ga not
                                if ga == 1: #cut 110
                                    x_ga_index   = self.enriched_mesh.n + 0
                                    p01_ga_index = self.enriched_mesh.n + 1
                                    p02_ga_index = self.enriched_mesh.n + 2
                                    p02_at_index = self.enriched_mesh.n + 3
                                    self.enriched_mesh.points = np.vstack((self.enriched_mesh.points, x_ga, p01_ga, p02_ga, p02_at))

                                    phi_at_pe01 = self.level_set_alphatheta_enriched.interpolate(trii, tri, p01_ga)
                                    phi_at_pe02 = self.level_set_alphatheta_enriched.interpolate(trii, tri, p02_ga)
                                    if phi_at_pe01 < 0:
                                        self.has_point_been_shifted = np.vstack((self.has_point_been_shifted, [1, 4], [1, 1], [1, 11]))
                                    else:
                                        self.has_point_been_shifted = np.vstack((self.has_point_been_shifted, [1, 4], [1, 11], [1, 1]))
                                    if phi_at_pe01 * phi_at_pe02 > 0:
                                        print('p01_ga and p02_ga same sign for phi_at (theta) trii, tri, i', trii, tri, i)

                                    phi_ga_pe = self.level_set_gammaalpha_enriched.interpolate(trii, tri, p02_at)
                                    if phi_ga_pe < 0:
                                        self.has_point_been_shifted = np.vstack((self.has_point_been_shifted, [1, 3]))
                                    else:
                                        self.has_point_been_shifted = np.vstack((self.has_point_been_shifted, [1, 2]))
                                    self.level_set_gammaalpha_enriched.phi = np.hstack((self.level_set_gammaalpha_enriched.phi, 0, 0, 0, phi_ga_pe))
                                    self.level_set_alphatheta_enriched.phi = np.hstack((self.level_set_alphatheta_enriched.phi, 0,
                                                                                        phi_at_pe01,
                                                                                        phi_at_pe02,
                                                                                        0))

                                    cut_Tau = np.zeros(self.background_mesh.n+1)
                                    cut_Tau[[e01_ga]] = np.array([1-taue01_ga, taue01_ga])
                                    if self.background_mesh.Tau[e01_ga[0], e01_ga[0]] != 0:
                                        other_points = self.background_mesh.Tau[e01_ga[0]].nonzero()[1]
                                        cut_Tau[e01_ga[0]] = 0
                                        cut_Tau[[other_points]] = cut_Tau[[other_points]] + (1-taue01_ga) * self.background_mesh.Tau[e01_ga[0], other_points].toarray()
                                    if self.background_mesh.Tau[e01_ga[1], e01_ga[1]] != 0:
                                        other_points = self.background_mesh.Tau[e01_ga[1]].nonzero()[1]
                                        cut_Tau[e01_ga[1]] = 0
                                        cut_Tau[[other_points]] = cut_Tau[[other_points]] + taue01_ga * self.background_mesh.Tau[e01_ga[1], other_points].toarray()
                                    cut_Tau[self.background_mesh.n] = p01_ga_index
                                    self.background_mesh.Tau = vstack((self.background_mesh.Tau, cut_Tau), format = 'lil')

                                    cut_Tau = np.zeros(self.background_mesh.n+1)
                                    cut_Tau[[e02]] = np.array([1-taue02_ga, taue02_ga])
                                    if self.background_mesh.Tau[e02[0], e02[0]] != 0:
                                        other_points = self.background_mesh.Tau[e02[0]].nonzero()[1]
                                        cut_Tau[e02[0]] = 0
                                        cut_Tau[[other_points]] = cut_Tau[[other_points]] + (1-taue02_ga) * self.background_mesh.Tau[e02[0], other_points].toarray()
                                    if self.background_mesh.Tau[e02[1], e02[1]] != 0:
                                        other_points = self.background_mesh.Tau[e02[1]].nonzero()[1]
                                        cut_Tau[e02[1]] = 0
                                        cut_Tau[[other_points]] = cut_Tau[[other_points]] + taue02_ga * self.background_mesh.Tau[e02[1], other_points].toarray()
                                    cut_Tau[self.background_mesh.n] = p02_ga_index
                                    self.background_mesh.Tau = vstack((self.background_mesh.Tau, cut_Tau), format = 'lil')

                                    cut_Tau = np.zeros(self.background_mesh.n+1)
                                    cut_Tau[[e02]] = np.array([1-taue02_at, taue02_at])
                                    if self.background_mesh.Tau[e02[0], e02[0]] != 0:
                                        other_points = self.background_mesh.Tau[e02[0]].nonzero()[1]
                                        cut_Tau[e02[0]] = 0
                                        cut_Tau[[other_points]] = cut_Tau[[other_points]] + (1-taue02_at) * self.background_mesh.Tau[e02[0], other_points].toarray()
                                    if self.background_mesh.Tau[e02[1], e02[1]] != 0:
                                        other_points = self.background_mesh.Tau[e02[1]].nonzero()[1]
                                        cut_Tau[e02[1]] = 0
                                        cut_Tau[[other_points]] = cut_Tau[[other_points]] + taue02_at * self.background_mesh.Tau[e02[1], other_points].toarray()
                                    cut_Tau[self.background_mesh.n] = p02_at_index
                                    self.background_mesh.Tau = vstack((self.background_mesh.Tau, cut_Tau), format = 'lil')

                                    trii0, trii1 = cGrid.least_angle_trii(self, np.intersect1d(e02, e01_ga)[0], p02_at_index, p01_ga_index, x_ga_index)
                                    trii2, trii3 = cGrid.least_angle_trii(self, p01_at_index, x_ga_index, np.setdiff1d(e02, e01_ga)[0], p02_ga_index)
                                    trii4 = np.hstack((p01_at_index, p01_ga_index, x_ga_index))
                                    trii5 = np.hstack((p02_at_index, p02_ga_index, x_ga_index))

                                    self.enriched_mesh.triangles_points_index[i] = trii4
                                    self.enriched_mesh.triangles_points_index = np.vstack((self.enriched_mesh.triangles_points_index, trii0, trii1, trii2, trii3, trii5))

                                    self.has_edge_been_handled[j02] = np.array([p02_ga_index, p02_at_index])
                                    self.has_edge_been_handled[j01_ga] = p01_ga_index

                                    self.enriched_mesh.n_tri = self.enriched_mesh.n_tri + 5
                                    self.enriched_mesh.n = self.enriched_mesh.n + 4

                                elif ga == 0:
                                    print('ga_at ga at = 1 0 0 not possible, cause triple point is in corner.')
                        elif ga_at == 2: #cut 2
                            x_ga_index   = self.enriched_mesh.n + 0
                            p02_ga_index = self.enriched_mesh.n + 1
                            p12_ga_index = self.enriched_mesh.n + 2
                            p02_at_index = self.enriched_mesh.n + 3
                            p12_at_index = self.enriched_mesh.n + 4

                            self.enriched_mesh.points = np.vstack((self.enriched_mesh.points, x_ga, p02_ga, p12_ga, p02_at, p12_at))
                            phi_at_pe02 = self.level_set_alphatheta_enriched.interpolate(trii, tri, p02_ga)
                            phi_at_pe12 = self.level_set_alphatheta_enriched.interpolate(trii, tri, p12_ga)
                            if phi_at_pe02 < 0:
                                self.has_point_been_shifted = np.vstack((self.has_point_been_shifted, [1, 4], [1, 1], [1, 11]))
                            else:
                                self.has_point_been_shifted = np.vstack((self.has_point_been_shifted, [1, 4], [1, 11], [1, 1]))
                            if phi_at_pe02 * phi_at_pe12 > 0:
                                print('p02_ga and p12_ga same sign for phi_at (theta) trii, tri, i', trii, tri, i)

                            phi_ga_pe02 = self.level_set_gammaalpha_enriched.interpolate(trii, tri, p02_at)
                            phi_ga_pe12 = self.level_set_gammaalpha_enriched.interpolate(trii, tri, p12_at)
                            if phi_ga_pe02 < 0:
                                self.has_point_been_shifted = np.vstack((self.has_point_been_shifted, [1, 3]))
                            else:
                                self.has_point_been_shifted = np.vstack((self.has_point_been_shifted, [1, 2]))
                            if phi_ga_pe12 < 0:
                                self.has_point_been_shifted = np.vstack((self.has_point_been_shifted, [1, 3]))
                            else:
                                self.has_point_been_shifted = np.vstack((self.has_point_been_shifted, [1, 2]))
                            if phi_ga_pe02 * phi_ga_pe12 > 0:
                                print('p02_at and p12_at same sign for phi_at (theta) trii, tri, i', trii, tri, i)

                            self.level_set_gammaalpha_enriched.phi = np.hstack((self.level_set_gammaalpha_enriched.phi, np.zeros(3), phi_ga_pe02, phi_ga_pe12))
                            self.level_set_alphatheta_enriched.phi = np.hstack((self.level_set_alphatheta_enriched.phi, 0, phi_at_pe02, phi_at_pe12, 0, 0))

                            print('e02, e12 ', e02, e12)

                            cut_Tau = np.zeros(self.background_mesh.n+1)
                            cut_Tau[[e02]] = np.array([1-taue02_ga, taue02_ga])
                            if self.background_mesh.Tau[e02[0], e02[0]] != 0:
                                other_points = self.background_mesh.Tau[e02[0]].nonzero()[1]
                                cut_Tau[e02[0]] = 0
                                cut_Tau[[other_points]] = cut_Tau[[other_points]] + (1-taue02_ga) * self.background_mesh.Tau[e02[0], other_points].toarray()
                            if self.background_mesh.Tau[e02[1], e02[1]] != 0:
                                other_points = self.background_mesh.Tau[e02[1]].nonzero()[1]
                                cut_Tau[e02[1]] = 0
                                cut_Tau[[other_points]] = cut_Tau[[other_points]] + taue02_ga * self.background_mesh.Tau[e02[1], other_points].toarray()
                            cut_Tau[self.background_mesh.n] = p01_ga_index
                            self.background_mesh.Tau = vstack((self.background_mesh.Tau, cut_Tau), format = 'lil')

                            cut_Tau = np.zeros(self.background_mesh.n+1)
                            cut_Tau[[e12]] = np.array([1-taue12_ga, taue12_ga])
                            if self.background_mesh.Tau[e12[0], e12[0]] != 0:
                                other_points = self.background_mesh.Tau[e12[0]].nonzero()[1]
                                cut_Tau[e12[0]] = 0
                                cut_Tau[[other_points]] = cut_Tau[[other_points]] + (1-taue12_ga) * self.background_mesh.Tau[e12[0], other_points].toarray()
                            if self.background_mesh.Tau[e12[1], e12[1]] != 0:
                                other_points = self.background_mesh.Tau[e12[1]].nonzero()[1]
                                cut_Tau[e12[1]] = 0
                                cut_Tau[[other_points]] = cut_Tau[[other_points]] + taue12_ga * self.background_mesh.Tau[e12[1], other_points].toarray()
                            cut_Tau[self.background_mesh.n] = p12_ga_index
                            self.background_mesh.Tau = vstack((self.background_mesh.Tau, cut_Tau), format = 'lil')

                            cut_Tau = np.zeros(self.background_mesh.n+1)
                            cut_Tau[[e02]] = np.array([1-taue02_at, taue02_at])
                            if self.background_mesh.Tau[e02[0], e02[0]] != 0:
                                other_points = self.background_mesh.Tau[e02[0]].nonzero()[1]
                                cut_Tau[e02[0]] = 0
                                cut_Tau[[other_points]] = cut_Tau[[other_points]] + (1-taue02_at) * self.background_mesh.Tau[e02[0], other_points].toarray()
                            if self.background_mesh.Tau[e02[1], e02[1]] != 0:
                                other_points = self.background_mesh.Tau[e02[1]].nonzero()[1]
                                cut_Tau[e02[1]] = 0
                                cut_Tau[[other_points]] = cut_Tau[[other_points]] + taue02_at * self.background_mesh.Tau[e02[1], other_points].toarray()
                            cut_Tau[self.background_mesh.n] = p01_at_index
                            self.background_mesh.Tau = vstack((self.background_mesh.Tau, cut_Tau), format = 'lil')

                            cut_Tau = np.zeros(self.background_mesh.n+1)
                            cut_Tau[[e12]] = np.array([1-taue12_at, taue12_at])
                            if self.background_mesh.Tau[e12[0], e12[0]] != 0:
                                other_points = self.background_mesh.Tau[e12[0]].nonzero()[1]
                                cut_Tau[e12[0]] = 0
                                cut_Tau[[other_points]] = cut_Tau[[other_points]] + (1-taue12_at) * self.background_mesh.Tau[e12[0], other_points].toarray()
                            if self.background_mesh.Tau[e12[1], e12[1]] != 0:
                                other_points = self.background_mesh.Tau[e12[1]].nonzero()[1]
                                cut_Tau[e12[1]] = 0
                                cut_Tau[[other_points]] = cut_Tau[[other_points]] + taue12_at * self.background_mesh.Tau[e12[1], other_points].toarray()
                            cut_Tau[self.background_mesh.n] = p12_at_index
                            self.background_mesh.Tau = vstack((self.background_mesh.Tau, cut_Tau), format = 'lil')

                            index_cutoff = np.intersect1d(e02, e12)[0]
                            if la.norm(self.enriched_mesh.points[index_cutoff] - p02_ga, 2) < la.norm(self.enriched_mesh.points[index_cutoff] - p02_at, 2):
                                #p02_ga is closer to the cutoff on e02, so p12_at is closer than p12_ga. else they can't cut
                                trii0, trii1 = cGrid.least_angle_trii(self, index_cutoff, p02_ga_index, p12_at_index, x_ga_index)
                                trii2, trii3, trii4 = cGrid.least_angle_trii_5p(self, x_ga_index, p12_ga_index, p02_at_index, np.setdiff1d(e12, index_cutoff)[0], np.setdiff1d(e02, index_cutoff)[0])
                            else:
                                trii0, trii1 = cGrid.least_angle_trii(self, index_cutoff, p12_ga_index, p02_at_index, x_ga_index)
                                trii2, trii3, trii4 = cGrid.least_angle_trii_5p(self, x_ga_index, p02_ga_index, p12_at_index, np.setdiff1d(e02, index_cutoff)[0], np.setdiff1d(e12, index_cutoff)[0])
                            trii5 = np.hstack((p02_ga_index, p02_at_index, x_ga_index))
                            trii6 = np.hstack((p12_ga_index, p12_at_index, x_ga_index))
                            self.enriched_mesh.triangles_points_index[i] = trii0
                            self.enriched_mesh.triangles_points_index = np.vstack((self.enriched_mesh.triangles_points_index, trii1, trii2, trii3, trii4, trii5, trii6))

                            self.has_edge_been_handled[j02] = np.array([p02_ga_index, p02_at_index])
                            self.has_edge_been_handled[j12] = np.array([p12_ga_index, p12_at_index])

                            self.enriched_mesh.n_tri = self.enriched_mesh.n_tri + 6
                            self.enriched_mesh.n = self.enriched_mesh.n + 5
                        elif ga_at == 0:
                            if ga == 1 and at == 1: #cut 011
                                x_ga_index   = self.enriched_mesh.n + 0
                                p01_ga_index = self.enriched_mesh.n + 1
                                p01_at_index = self.enriched_mesh.n + 2
                                self.enriched_mesh.points = np.vstack((self.enriched_mesh.points, x_ga, p01_ga, p01_at))

                                phi_at_pe = self.level_set_alphatheta_enriched.interpolate(trii, tri, p01_ga)
                                if phi_at_pe < 0:
                                    self.has_point_been_shifted = np.vstack((self.has_point_been_shifted, [1, 4], [1, 1]))
                                    if self.has_point_been_shifted[p11_ga_index, 1] == 1:
                                        print('p01_ga and p02_ga on same side of theta interface?')
                                else:
                                    self.has_point_been_shifted = np.vstack((self.has_point_been_shifted, [1, 4], [1, 11]))
                                    if self.has_point_been_shifted[p11_ga_index, 1] == 11:
                                        print('p01_ga and p02_ga on same side of theta interface?')

                                phi_ga_pe = self.level_set_gammaalpha_enriched.interpolate(trii, tri, p01_at)
                                if phi_ga_pe < 0:
                                    self.has_point_been_shifted = np.vstack((self.has_point_been_shifted, [1, 3]))
                                else:
                                    self.has_point_been_shifted = np.vstack((self.has_point_been_shifted, [1, 2]))
                                self.level_set_gammaalpha_enriched.phi = np.hstack((self.level_set_gammaalpha_enriched.phi, 0, 0, phi_ga_pe))
                                self.level_set_alphatheta_enriched.phi = np.hstack((self.level_set_alphatheta_enriched.phi, 0, phi_at_pe, 0))

                                cut_Tau = np.zeros(self.background_mesh.n+1)
                                cut_Tau[[e01_ga]] = np.array([1-taue01_ga, taue01_ga])
                                if self.background_mesh.Tau[e01_ga[0], e01_ga[0]] != 0:
                                    other_points = self.background_mesh.Tau[e01_ga[0]].nonzero()[1]
                                    cut_Tau[e01_ga[0]] = 0
                                    cut_Tau[[other_points]] = cut_Tau[[other_points]] + (1-taue01_ga) * self.background_mesh.Tau[e01_ga[0], other_points].toarray()
                                if self.background_mesh.Tau[e01_ga[1], e01_ga[1]] != 0:
                                    other_points = self.background_mesh.Tau[e01_ga[1]].nonzero()[1]
                                    cut_Tau[e01_ga[1]] = 0
                                    cut_Tau[[other_points]] = cut_Tau[[other_points]] + taue01_ga * self.background_mesh.Tau[e01_ga[1], other_points].toarray()
                                cut_Tau[self.background_mesh.n] = p01_ga_index
                                self.background_mesh.Tau = vstack((self.background_mesh.Tau, cut_Tau), format = 'lil')

                                cut_Tau = np.zeros(self.background_mesh.n+1)
                                cut_Tau[[e01_at]] = np.array([1-taue01_at, taue01_at])
                                if self.background_mesh.Tau[e01_at[0], e01_at[0]] != 0:
                                    other_points = self.background_mesh.Tau[e01_at[0]].nonzero()[1]
                                    cut_Tau[e01_at[0]] = 0
                                    cut_Tau[[other_points]] = cut_Tau[[other_points]] + (1-taue01_at) * self.background_mesh.Tau[e01_at[0], other_points].toarray()
                                if self.background_mesh.Tau[e01_at[1], e01_at[1]] != 0:
                                    other_points = self.background_mesh.Tau[e01_at[1]].nonzero()[1]
                                    cut_Tau[e01_at[1]] = 0
                                    cut_Tau[[other_points]] = cut_Tau[[other_points]] + taue01_at * self.background_mesh.Tau[e01_at[1], other_points].toarray()
                                cut_Tau[self.background_mesh.n] = p01_at_index
                                self.background_mesh.Tau = vstack((self.background_mesh.Tau, cut_Tau), format = 'lil')

                                trii0 = np.array([p11_ga_index, p11_at_index, x_ga_index])
                                trii1 = np.array([p11_ga_index, p01_at_index, x_ga_index])
                                trii2 = np.array([p11_at_index, p01_ga_index ,x_ga_index])
                                trii3, trii4 = cGrid.least_angle_trii(self, np.intersect1d(e01_ga, e01_at)[0], p01_ga_index, p01_at_index, x_ga_index)

                                self.enriched_mesh.triangles_points_index[i] = trii0
                                self.enriched_mesh.triangles_points_index = np.vstack((self.enriched_mesh.triangles_points_index, trii1, trii2, trii3, trii4))

                                self.has_edge_been_handled[j01_at] = p01_at_index
                                self.has_edge_been_handled[j01_ga] = p01_ga_index

                                self.enriched_mesh.n_tri = self.enriched_mesh.n_tri + 4
                                self.enriched_mesh.n = self.enriched_mesh.n + 3
                            elif ga + at == 3:
                                if ga == 1: #cut 012
                                    x_ga_index   = self.enriched_mesh.n + 0
                                    p01_ga_index = self.enriched_mesh.n + 1
                                    p01_at_index = self.enriched_mesh.n + 2
                                    p11_at_index = self.enriched_mesh.n + 3
                                    self.enriched_mesh.points = np.vstack((self.enriched_mesh.points, x_ga, p01_ga, p01_at, p11_at))

                                    phi_at_pe = self.level_set_alphatheta_enriched.interpolate(trii, tri, p01_ga)
                                    if phi_at_pe < 0:
                                        self.has_point_been_shifted = np.vstack((self.has_point_been_shifted, [1, 4], [1, 1]))
                                        if self.has_point_been_shifted[p11_ga_index, 1] == 1:
                                            print('p01_ga and p02_ga on same side of theta interface?')
                                    else:
                                        self.has_point_been_shifted = np.vstack((self.has_point_been_shifted, [1, 4], [1, 11]))
                                        if self.has_point_been_shifted[p11_ga_index, 1] == 11:
                                            print('p01_ga and p02_ga on same side of theta interface?')

                                    phi_ga_pe01 = self.level_set_gammaalpha_enriched.interpolate(trii, tri, p01_at)
                                    phi_ga_pe11 = self.level_set_gammaalpha_enriched.interpolate(trii, tri, p11_at)
                                    if phi_ga_pe01 < 0:
                                        self.has_point_been_shifted = np.vstack((self.has_point_been_shifted, [1, 3]))
                                    else:
                                        self.has_point_been_shifted = np.vstack((self.has_point_been_shifted, [1, 2]))
                                    if phi_ga_pe11 < 0:
                                        self.has_point_been_shifted = np.vstack((self.has_point_been_shifted, [1, 3]))
                                    else:
                                        self.has_point_been_shifted = np.vstack((self.has_point_been_shifted, [1, 2]))
                                    self.level_set_gammaalpha_enriched.phi = np.hstack((self.level_set_gammaalpha_enriched.phi, 0, 0, phi_ga_pe01, phi_ga_pe11))
                                    self.level_set_alphatheta_enriched.phi = np.hstack((self.level_set_alphatheta_enriched.phi, 0, phi_at_pe, np.zeros(2)))

                                    cut_Tau = np.zeros(self.background_mesh.n+1)
                                    cut_Tau[[e01_ga]] = np.array([1-taue01_ga, taue01_ga])
                                    if self.background_mesh.Tau[e01_ga[0], e01_ga[0]] != 0:
                                        other_points = self.background_mesh.Tau[e01_ga[0]].nonzero()[1]
                                        cut_Tau[e01_ga[0]] = 0
                                        cut_Tau[[other_points]] = cut_Tau[[other_points]] + (1-taue01_ga) * self.background_mesh.Tau[e01_ga[0], other_points].toarray()
                                    if self.background_mesh.Tau[e01_ga[1], e01_ga[1]] != 0:
                                        other_points = self.background_mesh.Tau[e01_ga[1]].nonzero()[1]
                                        cut_Tau[e01_ga[1]] = 0
                                        cut_Tau[[other_points]] = cut_Tau[[other_points]] + taue01_ga * self.background_mesh.Tau[e01_ga[1], other_points].toarray()
                                    cut_Tau[self.background_mesh.n] = p01_ga_index
                                    self.background_mesh.Tau = vstack((self.background_mesh.Tau, cut_Tau), format = 'lil')

                                    cut_Tau = np.zeros(self.background_mesh.n+1)
                                    cut_Tau[[e01_at]] = np.array([1-taue01_at, taue01_at])
                                    if self.background_mesh.Tau[e01_at[0], e01_at[0]] != 0:
                                        other_points = self.background_mesh.Tau[e01_at[0]].nonzero()[1]
                                        cut_Tau[e01_at[0]] = 0
                                        cut_Tau[[other_points]] = cut_Tau[[other_points]] + (1-taue01_at) * self.background_mesh.Tau[e01_at[0], other_points].toarray()
                                    if self.background_mesh.Tau[e01_at[1], e01_at[1]] != 0:
                                        other_points = self.background_mesh.Tau[e01_at[1]].nonzero()[1]
                                        cut_Tau[e01_at[1]] = 0
                                        cut_Tau[[other_points]] = cut_Tau[[other_points]] + taue01_at * self.background_mesh.Tau[e01_at[1], other_points].toarray()
                                    cut_Tau[self.background_mesh.n] = p01_at_index
                                    self.background_mesh.Tau = vstack((self.background_mesh.Tau, cut_Tau), format = 'lil')

                                    cut_Tau = np.zeros(self.background_mesh.n+1)
                                    cut_Tau[[e11_at]] = np.array([1-taue11_at, taue11_at])
                                    if self.background_mesh.Tau[e11_at[0], e11_at[0]] != 0:
                                        other_points = self.background_mesh.Tau[e11_at[0]].nonzero()[1]
                                        cut_Tau[e11_at[0]] = 0
                                        cut_Tau[[other_points]] = cut_Tau[[other_points]] + (1-taue11_at) * self.background_mesh.Tau[e11_at[0], other_points].toarray()
                                    if self.background_mesh.Tau[e11_at[1], e11_at[1]] != 0:
                                        other_points = self.background_mesh.Tau[e11_at[1]].nonzero()[1]
                                        cut_Tau[e11_at[1]] = 0
                                        cut_Tau[[other_points]] = cut_Tau[[other_points]] + taue11_at * self.background_mesh.Tau[e11_at[1], other_points].toarray()
                                    cut_Tau[self.background_mesh.n] = p11_at_index
                                    self.background_mesh.Tau = vstack((self.background_mesh.Tau, cut_Tau), format = 'lil')

                                    trii0 = np.array([p11_ga_index, p01_at_index, x_ga_index])
                                    trii1 = np.array([p11_ga_index, p11_at_index, x_ga_index])
                                    trii2, trii3 = cGrid.least_angle_trii(self, np.intersect1d(e01_ga, e01_at)[0], p01_ga_index, p01_at_index, x_ga_index)
                                    trii4, trii5 = cGrid.least_angle_trii(self, np.intersect1d(e01_ga, e11_at)[0], p01_ga_index, p11_at_index, x_ga_index)

                                    self.enriched_mesh.triangles_points_index[i] = trii0
                                    self.enriched_mesh.triangles_points_index = np.vstack((self.enriched_mesh.triangles_points_index, trii1, trii2, trii3, trii4, trii5))

                                    self.has_edge_been_handled[j01_at] = p01_at_index
                                    self.has_edge_been_handled[j11_at] = p11_at_index
                                    self.has_edge_been_handled[j01_ga] = p01_ga_index

                                    self.enriched_mesh.n_tri = self.enriched_mesh.n_tri + 5
                                    self.enriched_mesh.n = self.enriched_mesh.n + 4
                                elif at == 1: #cut 021
                                    x_ga_index = self.enriched_mesh.n + 0
                                    p01_ga_index = self.enriched_mesh.n + 1
                                    p11_ga_index = self.enriched_mesh.n + 2
                                    p01_at_index = self.enriched_mesh.n + 3


                                    self.enriched_mesh.points = np.vstack((self.enriched_mesh.points, x_ga, p01_ga, p11_ga, p01_at))
                                    phi_at_pe01 = self.level_set_alphatheta_enriched.interpolate(trii, tri, p01_ga)
                                    phi_at_pe11 = self.level_set_alphatheta_enriched.interpolate(trii, tri, p11_ga)
                                    if phi_at_pe01 < 0:
                                        self.has_point_been_shifted = np.vstack((self.has_point_been_shifted, [1, 4], [1, 1], [1, 11]))
                                    else:
                                        self.has_point_been_shifted = np.vstack((self.has_point_been_shifted, [1, 4], [1, 11], [1, 1]))
                                    if phi_at_pe01 * phi_at_pe11 > 0:
                                        print('p01_ga and p11_ga same sign for phi_at (theta) trii, tri, i', trii, tri, i)

                                    phi_ga_pe = self.level_set_gammaalpha_enriched.interpolate(trii, tri, p01_at)
                                    if phi_ga_pe < 0:
                                        self.has_point_been_shifted = np.vstack((self.has_point_been_shifted, [1, 3]))
                                    else:
                                        self.has_point_been_shifted = np.vstack((self.has_point_been_shifted, [1, 2]))

                                    self.level_set_gammaalpha_enriched.phi = np.hstack((self.level_set_gammaalpha_enriched.phi, np.zeros(3), phi_ga_pe))
                                    self.level_set_alphatheta_enriched.phi = np.hstack((self.level_set_alphatheta_enriched.phi, 0, phi_at_pe01, phi_at_pe11 ,0))

                                    cut_Tau = np.zeros(self.background_mesh.n+1)
                                    cut_Tau[[e01_ga]] = np.array([1-taue01_ga, taue01_ga])
                                    if self.background_mesh.Tau[e01_ga[0], e01_ga[0]] != 0:
                                        other_points = self.background_mesh.Tau[e01_ga[0]].nonzero()[1]
                                        cut_Tau[e01_ga[0]] = 0
                                        cut_Tau[[other_points]] = cut_Tau[[other_points]] + (1-taue01_ga) * self.background_mesh.Tau[e01_ga[0], other_points].toarray()
                                    if self.background_mesh.Tau[e01_ga[1], e01_ga[1]] != 0:
                                        other_points = self.background_mesh.Tau[e01_ga[1]].nonzero()[1]
                                        cut_Tau[e01_ga[1]] = 0
                                        cut_Tau[[other_points]] = cut_Tau[[other_points]] + taue01_ga * self.background_mesh.Tau[e01_ga[1], other_points].toarray()
                                    cut_Tau[self.background_mesh.n] = p01_ga_index
                                    self.background_mesh.Tau = vstack((self.background_mesh.Tau, cut_Tau), format = 'lil')

                                    cut_Tau = np.zeros(self.background_mesh.n+1)
                                    cut_Tau[[e11_ga]] = np.array([1-taue11_ga, taue11_ga])
                                    if self.background_mesh.Tau[e11_ga[0], e11_ga[0]] != 0:
                                        other_points = self.background_mesh.Tau[e11_ga[0]].nonzero()[1]
                                        cut_Tau[e11_ga[0]] = 0
                                        cut_Tau[[other_points]] = cut_Tau[[other_points]] + (1-taue11_ga) * self.background_mesh.Tau[e11_ga[0], other_points].toarray()
                                    if self.background_mesh.Tau[e11_ga[1], e11_ga[1]] != 0:
                                        other_points = self.background_mesh.Tau[e11_ga[1]].nonzero()[1]
                                        cut_Tau[e11_ga[1]] = 0
                                        cut_Tau[[other_points]] = cut_Tau[[other_points]] + taue11_ga * self.background_mesh.Tau[e11_ga[1], other_points].toarray()
                                    cut_Tau[self.background_mesh.n] = p11_ga_index
                                    self.background_mesh.Tau = vstack((self.background_mesh.Tau, cut_Tau), format = 'lil')

                                    cut_Tau = np.zeros(self.background_mesh.n+1)
                                    cut_Tau[[e01_at]] = np.array([1-taue01_at, taue01_at])
                                    if self.background_mesh.Tau[e01_at[0], e01_at[0]] != 0:
                                        other_points = self.background_mesh.Tau[e01_at[0]].nonzero()[1]
                                        cut_Tau[e01_at[0]] = 0
                                        cut_Tau[[other_points]] = cut_Tau[[other_points]] + (1-taue01_at) * self.background_mesh.Tau[e01_at[0], other_points].toarray()
                                    if self.background_mesh.Tau[e01_at[1], e01_at[1]] != 0:
                                        other_points = self.background_mesh.Tau[e01_at[1]].nonzero()[1]
                                        cut_Tau[e01_at[1]] = 0
                                        cut_Tau[[other_points]] = cut_Tau[[other_points]] + taue01_at * self.background_mesh.Tau[e01_at[1], other_points].toarray()
                                    cut_Tau[self.background_mesh.n] = p01_at_index
                                    self.background_mesh.Tau = vstack((self.background_mesh.Tau, cut_Tau), format = 'lil')

                                    trii0 = np.array([p11_at_index, p01_ga_index, x_ga_index])
                                    trii1 = np.array([p11_at_index, p11_ga_index, x_ga_index])
                                    trii2, trii3 = cGrid.least_angle_trii(self, np.intersect1d(e01_at, e01_ga)[0], p01_at_index, p01_ga_index, x_ga_index)
                                    trii4, trii5 = cGrid.least_angle_trii(self, np.intersect1d(e01_at, e11_ga)[0], p01_at_index, p11_ga_index, x_ga_index)

                                    self.enriched_mesh.triangles_points_index[i] = trii0
                                    self.enriched_mesh.triangles_points_index = np.vstack((self.enriched_mesh.triangles_points_index, trii1, trii2, trii3, trii4, trii5))

                                    self.has_edge_been_handled[j01_at] = p01_at_index
                                    self.has_edge_been_handled[j01_ga] = p01_ga_index
                                    self.has_edge_been_handled[j11_ga] = p11_ga_index

                                    self.enriched_mesh.n_tri = self.enriched_mesh.n_tri + 5
                                    self.enriched_mesh.n = self.enriched_mesh.n + 4
                            elif ga == 0: #cut 002 001
                                 pass #should be dealt with in bend
                            elif at == 0:
                                if ga == 1: #cut 010
                                    #triple point = p11_ga
                                    p01_ga_index = self.enriched_mesh.n + 0
                                    x_ga_index = p11_ga_index
                                    self.enriched_mesh.points = np.vstack((self.enriched_mesh.points, p01_ga))
                                    phi_at_pe = self.level_set_alphatheta_enriched.interpolate(trii, tri, p01_ga)
                                    if phi_at_pe < 0:
                                        self.has_point_been_shifted = np.vstack((self.has_point_been_shifted, [1, 1]))
                                    else:
                                        self.has_point_been_shifted = np.vstack((self.has_point_been_shifted, [1, 11]))
                                    if self.has_point_been_shifted[p11_ga_index, 1]%4 != 0:
                                        print('cut 010 triple shift/bend/cut.')
                                        print('p11_index should be triple point but isnt set as one in has_point_been_shifted')
                                        self.has_point_been_shifted[p11_ga_index] = [1, 8]

                                    self.level_set_gammaalpha_enriched.phi = np.hstack((self.level_set_gammaalpha_enriched.phi, 0))
                                    self.level_set_alphatheta_enriched.phi = np.hstack((self.level_set_alphatheta_enriched.phi, phi_at_pe))

                                    cut_Tau = np.zeros(self.background_mesh.n+1)
                                    cut_Tau[[e01_ga]] = np.array([1-taue01_ga, taue01_ga])
                                    if self.background_mesh.Tau[e01_ga[0], e01_ga[0]] != 0:
                                        other_points = self.background_mesh.Tau[e01_ga[0]].nonzero()[1]
                                        cut_Tau[e01_ga[0]] = 0
                                        cut_Tau[[other_points]] = cut_Tau[[other_points]] + (1-taue01_ga) * self.background_mesh.Tau[e01_ga[0], other_points].toarray()
                                    if self.background_mesh.Tau[e01_ga[1], e01_ga[1]] != 0:
                                        other_points = self.background_mesh.Tau[e01_ga[1]].nonzero()[1]
                                        cut_Tau[e01_ga[1]] = 0
                                        cut_Tau[[other_points]] = cut_Tau[[other_points]] + taue01_ga * self.background_mesh.Tau[e01_ga[1], other_points].toarray()
                                    cut_Tau[self.background_mesh.n] = p01_ga_index
                                    self.background_mesh.Tau = vstack((self.background_mesh.Tau, cut_Tau), format = 'lil')

                                    trii0 = np.array([p11_ga_index, p01_at_index, p01_ga_index])
                                    trii1 = np.array([p11_ga_index, p11_at_index, p01_ga_index])

                                    self.enriched_mesh.triangles_points_index[i] = trii0
                                    self.enriched_mesh.triangles_points_index = np.vstack((self.enriched_mesh.triangles_points_index, trii1))

                                    self.has_edge_been_handled[j01_ga] = p01_ga_index

                                    self.enriched_mesh.n_tri = self.enriched_mesh.n_tri + 1
                                    self.enriched_mesh.n = self.enriched_mesh.n + 1
                                elif ga == 2: #cut 020
                                    x_ga_index = self.enriched_mesh.n + 0
                                    self.level_set_gammaalpha_enriched.phi = np.hstack((self.level_set_gammaalpha_enriched.phi,0))
                                    self.level_set_alphatheta_enriched.phi = np.hstack((self.level_set_alphatheta_enriched.phi,0))


                                    #one of two ga points must be triple point
                                    if la.norm(p01_ga - x_ga) < 1e-13: #p01_ga is triple point
                                        point_to_add = p11_ga
                                        e_to_add = e11_ga
                                        j_to_add = j11_ga
                                        x_ga = p01_ga
                                        e_ga = e01_ga
                                        j_ga = j01_ga
                                        taue_ga = taue01_ga
                                    else:
                                        point_to_add = p01_ga
                                        e_to_add = e01_ga
                                        j_to_add = j01_ga
                                        x_ga = p11_ga
                                        e_ga = e11_ga
                                        j_ga = j11_ga
                                        taue_ga = taue11_ga

                                    point_to_add_index = self.enriched_mesh.n + 1

                                    self.enriched_mesh.points = np.vstack((self.enriched_mesh.points, x_ga, point_to_add))
                                    phi_at_pe = self.level_set_alphatheta_enriched.interpolate(trii, tri, point_to_add)
                                    if phi_at_pe < 0:
                                        self.has_point_been_shifted = np.vstack((self.has_point_been_shifted, [1, 4], [1, 1]))
                                    else:
                                        self.has_point_been_shifted = np.vstack((self.has_point_been_shifted, [1, 4], [1, 11]))
                                    trii0 = np.hstack((np.intersect1d(e01_ga, e11_ga)[0], point_to_add, x_ga))
                                    trii1, trii2 = cGrid.least_angle_trii(self, np.setdiff1d(trii, np.array([p01_at_index, p11_at_index]))[0], np.setdiff1d(e_ga, e_to_add)[0], point_to_add_index, x_ga_index)

                                    self.level_set_gammaalpha_enriched.phi = np.hstack((self.level_set_gammaalpha_enriched.phi, 0))
                                    self.level_set_alphatheta_enriched.phi = np.hstack((self.level_set_alphatheta_enriched.phi, phi_at_pe))

                                    cut_Tau = np.zeros(self.background_mesh.n+1)
                                    cut_Tau[[e_ga]] = np.array([1-taue_ga, taue_ga])
                                    if self.background_mesh.Tau[e_ga[0], e_ga[0]] != 0:
                                        other_points = self.background_mesh.Tau[e_ga[0]].nonzero()[1]
                                        cut_Tau[e_ga[0]] = 0
                                        cut_Tau[[other_points]] = cut_Tau[[other_points]] + (1-taue_ga) * self.background_mesh.Tau[e_ga[0], other_points].toarray()
                                    if self.background_mesh.Tau[e_ga[1], e_ga[1]] != 0:
                                        other_points = self.background_mesh.Tau[e_ga[1]].nonzero()[1]
                                        cut_Tau[e_ga[1]] = 0
                                        cut_Tau[[other_points]] = cut_Tau[[other_points]] + taue_ga * self.background_mesh.Tau[e_ga[1], other_points].toarray()
                                    cut_Tau[self.background_mesh.n] = point_to_add_index
                                    self.background_mesh.Tau = vstack((self.background_mesh.Tau, cut_Tau), format = 'lil')


                                    self.enriched_mesh.triangles_points_index[i] = trii0
                                    self.enriched_mesh.triangles_points_index = np.vstack((self.enriched_mesh.triangles_points_index, trii1, trii2))

                                    self.interface_gammaalpha.edges_index = np.vstack((self.interface_gammaalpha.edges_index, np.sort([point_to_add_index, x_ga_index])))

                                    self.has_edge_been_handled[j_to_add] = point_to_add_index
                                    self.has_edge_been_handled[j_ga] = x_ga_index

                                    self.enriched_mesh.n_tri = self.enriched_mesh.n_tri + 2
                                    self.enriched_mesh.n = self.enriched_mesh.n + 2



                        self.triple_points_index = np.hstack((self.triple_points_index, x_ga_index))
                    else:
                        print('t in (0,1) but nothing done t', t, 'tri ', tri, 'trii ', trii )
                        print(where_lambda_smaller_other_delta.shape[0], self.has_point_been_shifted[trii],'\n')
                else:
#                    interface_ga_at_where_index = np.append(interface_ga_at_where_index,i)
                    interface_ga_where_index = np.append(interface_ga_where_index,i)
                    interface_at_where_index = np.append(interface_at_where_index,i)

            elif ga == 2:
                interface_ga_where_index = np.append(interface_ga_where_index,i)
            elif at == 2:
                interface_at_where_index = np.append(interface_at_where_index,i)
        return interface_ga_where_index, interface_at_where_index

    def cut(self, triangles_points_index, which_tri, Is_point_BP, edge_index_mesh, old_phi, which_phi):
        for i in range(0,len(which_tri)):
            trii = triangles_points_index[which_tri[i]]
            #Do nothing if any point is triple point, as this has already been handled
#            if np.intersect1d(trii, self.triple_points_index).shape[0] == 0:
            if 1 > 0:
                tri = self.enriched_mesh.points[trii]
                pii = 0
                amount_new=0
                k=0
                for edgei in np.array([[0,1],[0,2],[1,2]]):
                    edge = tri[edgei]
                    edgeii = trii[edgei]
                    sorted_edgeii = np.sort(edgeii)

                    ga_no_shift = True
#            #if all points of the triangle are in the overlap, then dont cut.
#                    if which_phi == 1 and any(self.level_set_alphatheta_enriched.phi[edgeii] > 0):
#                        ga_no_shift = False

                    j = edge_index_mesh[sorted_edgeii[0],sorted_edgeii[1]]

                    B_edge = False
                    #check if edge intersects interface gammaalpha
                    if old_phi[edgeii[0]] * old_phi[edgeii[1]] < 0 and ga_no_shift:
                        pii = pii + 1
                        taue = -old_phi[edgeii[0]]/(old_phi[edgeii[1]] - old_phi[edgeii[0]])
                        pe = (1-taue)*edge[0] + taue*edge[1]
                        #Delta stuff
                        e0_delta = taue > self.delta
                        e1_delta = taue < 1-self.delta
                        e0e1_delta = e0_delta and e1_delta
                        #If one of the points is a boundary point and the other is not, only the not boundary point is allowed to shift
                        if any(Is_point_BP[edgeii,0] == 1) and not(all(Is_point_BP[edgeii,0] == 1)):
                            if Is_point_BP[edgeii[0],0] == 1 and not(e0_delta):
                                B_edge = True
                            elif Is_point_BP[edgeii[1],0] == 1 and not(e1_delta):
                                B_edge = True

                        #If both points are BP, but on different boundaries (not including corner point), dont shift
                        if all(Is_point_BP[edgeii,0] == 1) and not(Is_point_BP[edgeii[0],1] == Is_point_BP[edgeii[1],1]) and all(Is_point_BP[edgeii,1] < 5):
                            B_edge = True

                        #Dont shift corner point
                        if any(Is_point_BP[edgeii,1] == 5):
                            if Is_point_BP[edgeii[0],1] == 5 and not(e0_delta):
                                B_edge = True
                            elif Is_point_BP[edgeii[1],1] == 5 and not(e1_delta):
                                B_edge = True

                        #Not able to shift if point of edge is already shifted to another interface
                        if which_phi == 2:
                            if self.has_point_been_shifted[edgeii[0],0] == 1 and not(e0_delta) and not(any(self.has_point_been_shifted[edgeii[0],1] == [2, 3])):
                                B_edge = True
                            elif self.has_point_been_shifted[edgeii[1],0] == 1  and not(e1_delta) and not(any(self.has_point_been_shifted[edgeii[1],1] == [2, 3])):
                                B_edge = True
                        else:
                            if self.has_point_been_shifted[edgeii[0],0] == 1 and not(e0_delta) and not(self.has_point_been_shifted[edgeii[0],1]%10 == which_phi):
                                B_edge = True
                            elif self.has_point_been_shifted[edgeii[1],0] == 1  and not(e1_delta) and not(self.has_point_been_shifted[edgeii[1],1]%10 == which_phi):
                                B_edge = True


                        if B_edge or e0e1_delta:
                            amount_new = amount_new + 1
                            if self.has_edge_been_handled[j,which_phi - 1] == -1:
                                self.enriched_mesh.points = np.vstack((self.enriched_mesh.points,pe))
                                if not(any(edgeii > self.N)): #not(any(self.has_point_been_shifted[edgeii, 1]%4 == 0)):
                                    cut_Tau = np.zeros(self.background_mesh.n+1)
                                    cut_Tau[[edgeii]] = np.array([1-taue, taue])
                                    if self.background_mesh.Tau[edgeii[0], edgeii[0]] != 0:
                                        other_points = self.background_mesh.Tau[edgeii[0]].nonzero()[1]
                                        cut_Tau[edgeii[0]] = 0
                                        cut_Tau[[other_points]] = cut_Tau[[other_points]] + (1-taue) * self.background_mesh.Tau[edgeii[0], other_points].toarray()
                                    if self.background_mesh.Tau[edgeii[1], edgeii[1]] != 0:
                                        other_points = self.background_mesh.Tau[edgeii[1]].nonzero()[1]
                                        cut_Tau[edgeii[1]] = 0
                                        cut_Tau[[other_points]] = cut_Tau[[other_points]] + taue * self.background_mesh.Tau[edgeii[1], other_points].toarray()
                                    cut_Tau[self.background_mesh.n] = self.enriched_mesh.n
                                    self.background_mesh.Tau = vstack((self.background_mesh.Tau, cut_Tau), format = 'lil')

                                if any(self.level_set_gammaalpha_enriched.phi[trii] != 0):
                                    phi_ga_pe = self.level_set_gammaalpha_enriched.interpolate(trii,tri,pe)
                                else:
                                    phi_ga_pe = 0

                                if which_phi == 2 and phi_ga_pe < 0:
                                    self.has_point_been_shifted = np.vstack((self.has_point_been_shifted, [1, 3]))
                                else:
                                    if which_phi == 1:
                                        phi_at_pe = self.level_set_alphatheta_enriched.interpolate(trii,tri,pe)
                                        if phi_at_pe < 0:
                                            self.has_point_been_shifted = np.vstack((self.has_point_been_shifted, [1, 1]))
                                        else:
                                            self.has_point_been_shifted = np.vstack((self.has_point_been_shifted, [1, 11]))
                                    elif phi_ga_pe > 0:
                                        self.has_point_been_shifted = np.vstack((self.has_point_been_shifted, [1, 2]))
                                    else:
                                        other_trii = self.enriched_mesh.triangles_points_index[np.setdiff1d(self.enriched_mesh.edge_in_tri[j], i)[0]]
                                        phi_ga_other_trii = self.level_set_gammaalpha_enriched.phi[np.setdiff1d(other_trii, edgeii)[0]]
                                        if phi_ga_other_trii < 0:
                                            self.has_point_been_shifted = np.vstack((self.has_point_been_shifted, [1, 3]))
                                        else:
                                            self.has_point_been_shifted = np.vstack((self.has_point_been_shifted, [1, 2]))


                                if which_phi == 1:
                                    self.level_set_gammaalpha_enriched.phi = np.append(self.level_set_gammaalpha_enriched.phi, 0)
                                    self.level_set_alphatheta_enriched.phi = np.append(self.level_set_alphatheta_enriched.phi, phi_at_pe)
                                elif which_phi == 2:
                                    self.level_set_alphatheta_enriched.phi = np.append(self.level_set_alphatheta_enriched.phi, 0)
                                    self.level_set_gammaalpha_enriched.phi = np.append(self.level_set_gammaalpha_enriched.phi, phi_ga_pe)
                            elif all(self.level_set_gammaalpha_enriched.phi[trii] == 0) and which_phi == 2:
                                self.level_set_gammaalpha_enriched.phi[self.has_edge_been_handled[j,1]] = 0
                                other_trii = self.enriched_mesh.triangles_points_index[np.setdiff1d(self.enriched_mesh.edge_in_tri[j], i)[0]]
                                phi_ga_other_trii = self.level_set_gammaalpha_enriched.phi[np.setdiff1d(other_trii, edgeii)[0]]
                                if phi_ga_other_trii < 0:
                                    self.has_point_been_shifted[self.has_edge_been_handled[j,1]] =  [1, 3]
                                else:
                                    self.has_point_been_shifted[self.has_edge_been_handled[j,1]] = [1, 2]
                            if pii == 1:
                                p0 = pe
                                if self.has_edge_been_handled[j,0] == -1:
                                    p0_index = self.enriched_mesh.n
                                    self.enriched_mesh.n = self.enriched_mesh.n + 1
                                else:
                                    p0_index = self.has_edge_been_handled[j,0]
                                    if p0_index < self.N:
                                        print('0',p0_index, self.has_edge_been_handled[j,0])
                                e0ii =  edgeii
                                e0 = edgei
                                j0 = j
                                trii0_1 = np.hstack((np.setdiff1d(trii, edgeii[0]),p0_index))
                                trii1_1 = np.hstack((np.setdiff1d(trii, edgeii[1]),p0_index))
                            if pii == 2:
                                p1 = pe
                                if self.has_edge_been_handled[j,0] == -1:
                                    p1_index = self.enriched_mesh.n
                                    self.enriched_mesh.n = self.enriched_mesh.n + 1
                                else:
                                    p1_index = self.has_edge_been_handled[j,0]
                                    if p1_index < self.N:
                                        print('1',p1_index,self.has_edge_been_handled[j,0])
                                e1ii = edgeii
                                e1 = edgei
                                j1 = j
                                if amount_new == 1:
                                    trii0_1 = np.hstack((np.setdiff1d(tri, edgeii[0], p1_index)))
                                    trii1_1 = np.hstack((np.setdiff1d(tri, edgeii[1], p1_index)))
                                    
                if amount_new == 2:
                    if self.has_edge_been_handled[j0,0] == -1:
                        self.enriched_mesh.edges_index[j0] = np.hstack((np.setdiff1d(e0ii,e1ii), p0_index))
                        self.enriched_mesh.edges_index = np.vstack([self.enriched_mesh.edges_index, np.hstack((np.intersect1d(e0ii,e1ii), p0_index))])
                    if self.has_edge_been_handled[j1,0] == -1:
                        self.enriched_mesh.edges_index[j1] = np.hstack((np.setdiff1d(e1ii,e0ii), p1_index))
                        self.enriched_mesh.edges_index = np.vstack([self.enriched_mesh.edges_index, np.hstack((np.intersect1d(e0ii,e1ii), p1_index))])
                    self.enriched_mesh.edges_index = np.vstack([self.enriched_mesh.edges_index, np.hstack((np.setdiff1d(e1ii,e0ii), p0_index)), np.array([p0_index, p1_index])])

                    trii0_1, trii1_1 = cGrid.least_angle_trii(self, np.setdiff1d(e0ii, e1ii), np.setdiff1d(e1ii, e0ii), p0_index, p1_index)
                    trii2 = np.hstack((np.intersect1d(e0ii, e1ii)[0], p0_index, p1_index))
                    self.enriched_mesh.triangles_points_index[which_tri[i]] = trii0_1
                    self.enriched_mesh.triangles_points_index = np.vstack((self.enriched_mesh.triangles_points_index,trii1_1))
                    self.enriched_mesh.triangles_points_index = np.vstack((self.enriched_mesh.triangles_points_index,trii2))

                    self.enriched_mesh.n_tri = self.enriched_mesh.n_tri + 2


                    tri0_1 = self.enriched_mesh.points[self.enriched_mesh.triangles_points_index[which_tri[i]]]
                    tri1_1 = self.enriched_mesh.points[self.enriched_mesh.triangles_points_index[-2]]
                    tri2 = self.enriched_mesh.points[self.enriched_mesh.triangles_points_index[-1]]

                    area0_1 = cGrid.area(tri0_1)
                    area1_1 = cGrid.area(tri1_1)
                    area2 = cGrid.area(tri2)
                    if np.abs(area0_1) <= 1e-14 or np.abs(area1_1) <= 1e-14 or np.abs(area2) <= 1e-14:
                        print('area 2 new points in tri', area0_1,area1_1,area2)

                    self.has_edge_been_handled[j0,:] = p0_index
                    self.has_edge_been_handled[j1,:] = p1_index
                elif amount_new == 1:
                    index_cutoff_other_tri = np.setdiff1d(trii, e0ii)[0]


                    if self.has_edge_been_handled[j0,0] == -1:
                        self.enriched_mesh.edges_index[j0] = np.array([e0ii[0], p0_index])
                        self.enriched_mesh.edges_index = np.vstack([self.enriched_mesh.edges_index, np.array([e0ii[1], p0_index])])
                        self.has_edge_been_handled[j0,:] = p0_index
                    self.enriched_mesh.edges_index = np.vstack([self.enriched_mesh.edges_index, np.hstack((index_cutoff_other_tri, p0_index))])

                    self.enriched_mesh.triangles_points_index[which_tri[i]] = trii0_1
                    self.enriched_mesh.triangles_points_index = np.vstack((self.enriched_mesh.triangles_points_index,trii1_1))
                    self.enriched_mesh.n_tri = self.enriched_mesh.n_tri + 1

                    area0_1 = cGrid.area(self.enriched_mesh.points[trii0_1])
                    area1_1 = cGrid.area(self.enriched_mesh.points[trii1_1])
                    if np.abs(area0_1) <= 1e-14:
                        print('cut area0_1 new point in tri', area0_1, area1_1, 'tri', tri, 'trii', trii, 'which_phi ', which_phi,'which_tri ', which_tri[i])
                    if np.abs(area1_1) <= 1e-14:
                        print('cut area1_1 new point in tri', area1_1, area0_1, 'which_phi ', which_phi,'which_tri ', which_tri[i])
                if pii == 3:
                    print('pii = 3 at i',i)
                    print(tri)






    ### When both level-set functions change sign in a triangle cutting has soimetimes to be done differently
    def cut_twice(self, triangles_points_index, which_tri, Is_point_BP, edge_index_mesh, phi0 , phi1, which_phi0, which_phi1):
        for i in range(0,len(which_tri)):
            trii = triangles_points_index[which_tri[i]]
            #Do nothing if any point is (not shifted!) triple point (not has_been_shifted[:,1] == 8), as this has already been handled
            if 1 > 0:
                tri = self.enriched_mesh.points[trii]
                pii0 = 0
                pii1 = 0
                amount_new0 = 0
                amount_new1 = 0
                for edgei in np.array([[0,1],[0,2],[1,2]]):
                    amount_new_edge = 0
                    edge = tri[edgei]
                    edgeii = trii[edgei]
                    sorted_edgeii = np.sort(edgeii)
                    j = edge_index_mesh[sorted_edgeii[0],sorted_edgeii[1]]
                    B_edge = False
                    #check if edge intersects interface gammaalpha
                    if phi0[edgeii[0]] * phi0[edgeii[1]] < 0:
                        pii0 = pii0 + 1
                        taue = -phi0[edgeii[0]]/(phi0[edgeii[1]] - phi0[edgeii[0]])
                        pe = (1-taue)*edge[0] + taue*edge[1]
                        #Delta stuff
                        e0_delta = taue > self.delta
                        e1_delta = taue < 1-self.delta
                        e0e1_delta = e0_delta and e1_delta
                        if any(Is_point_BP[edgeii,0] == 1) and not(all(Is_point_BP[edgeii,0] == 1)):
                            if Is_point_BP[edgeii[0],0] == 1 and not(e0_delta):
                                B_edge = True
                            elif Is_point_BP[edgeii[1],0] == 1 and not(e1_delta):
                                B_edge = True

                        if all(Is_point_BP[edgeii,0] == 1) and not(Is_point_BP[edgeii[0],1] == Is_point_BP[edgeii[1],1]) and all(Is_point_BP[edgeii,1] < 5):
                            B_edge = True

                        if any(Is_point_BP[edgeii,1] == 5):
                            if Is_point_BP[edgeii[0],1] == 5 and not(e0_delta):
                                B_edge = True
                            elif Is_point_BP[edgeii[1],1] == 5 and not(e1_delta):
                                B_edge = True

                        #Not able to shift if point of edge is already shifted to another interface
                        if which_phi0 == 2:
                            if self.has_point_been_shifted[edgeii[0],0] == 1 and not(e0_delta) and not(any(self.has_point_been_shifted[edgeii[0],1] == [2, 3])):
                                B_edge = True
                            elif self.has_point_been_shifted[edgeii[1],0] == 1  and not(e1_delta) and not(any(self.has_point_been_shifted[edgeii[1],1] == [2, 3])):
                                B_edge = True
                        else:
                            if self.has_point_been_shifted[edgeii[0],0] == 1 and not(e0_delta) and not(self.has_point_been_shifted[edgeii[0],1]%10 == which_phi0):
                                B_edge = True
                            elif self.has_point_been_shifted[edgeii[1],0] == 1  and not(e1_delta) and not(self.has_point_been_shifted[edgeii[1],1]%10 == which_phi0):
                                B_edge = True
                        if B_edge or e0e1_delta:
                            amount_new0 = amount_new0 + 1
                            amount_new_edge = amount_new_edge + 1
                            if self.has_edge_been_handled[j,which_phi0-1] == -1:
                                self.enriched_mesh.points = np.vstack((self.enriched_mesh.points,pe))
                                if not(any(edgeii > self.N)): #not(any(self.has_point_been_shifted[edgeii, 1]%4 == 0)):
                                    cut_Tau = np.zeros(self.background_mesh.n+1)
                                    cut_Tau[[edgeii]] = np.array([1-taue, taue])
                                    if self.background_mesh.Tau[edgeii[0], edgeii[0]] != 0:
                                        other_points = self.background_mesh.Tau[edgeii[0]].nonzero()[1]
                                        cut_Tau[edgeii[0]] = 0
                                        cut_Tau[[other_points]] = cut_Tau[[other_points]] + (1-taue) * self.background_mesh.Tau[edgeii[0], other_points].toarray()
                                    if self.background_mesh.Tau[edgeii[1], edgeii[1]] != 0:
                                        other_points = self.background_mesh.Tau[edgeii[1]].nonzero()[1]
                                        cut_Tau[edgeii[1]] = 0
                                        cut_Tau[[other_points]] = cut_Tau[[other_points]] + taue * self.background_mesh.Tau[edgeii[1], other_points].toarray()
                                    cut_Tau[self.background_mesh.n] = self.enriched_mesh.n
                                    self.background_mesh.Tau = vstack((self.background_mesh.Tau, cut_Tau), format = 'lil')
                                if which_phi0 == 1:
                                    phi_at_pe = self.level_set_alphatheta_enriched.interpolate(trii,tri,pe)
                                    self.level_set_gammaalpha_enriched.phi = np.append(self.level_set_gammaalpha_enriched.phi, 0)
                                    self.level_set_alphatheta_enriched.phi = np.append(self.level_set_alphatheta_enriched.phi, phi_at_pe)
                                    if phi_at_pe < 0:
                                        self.has_point_been_shifted = np.vstack((self.has_point_been_shifted, [1, 1]))
                                    else:
                                        self.has_point_been_shifted = np.vstack((self.has_point_been_shifted, [1, 11]))

                                elif which_phi0 == 2:
                                    phi_ga_pe = self.level_set_gammaalpha_enriched.interpolate(trii,tri,pe)
                                    if phi_ga_pe < 0:
                                        self.has_point_been_shifted = np.vstack((self.has_point_been_shifted, [1, 3]))
                                    else:
                                        self.has_point_been_shifted = np.vstack((self.has_point_been_shifted, [1, 2]))
                                    self.level_set_alphatheta_enriched.phi = np.append(self.level_set_alphatheta_enriched.phi, 0)
                                    self.level_set_gammaalpha_enriched.phi = np.append(self.level_set_gammaalpha_enriched.phi, phi_ga_pe)

                            if pii0 == 1:
                                p00 = pe
                                if self.has_edge_been_handled[j,which_phi0-1] == -1:
                                    p00_index = self.enriched_mesh.n
                                    self.enriched_mesh.n = self.enriched_mesh.n + 1
                                else:
                                    p00_index = self.has_edge_been_handled[j,which_phi0-1]
                                    if p00_index < self.N:
                                        print('0',p00_index, self.has_edge_been_handled[j,which_phi0-1])
                                e00ii = edgeii
                                e00 = edgei
                                j00 = j

                            if pii0 == 2:
                                p10 = pe
                                if self.has_edge_been_handled[j,which_phi0-1] == -1:
                                    p10_index = self.enriched_mesh.n
                                    self.enriched_mesh.n = self.enriched_mesh.n + 1
                                else:
                                    p10_index = self.has_edge_been_handled[j,0]
                                    if p10_index < self.N:
                                        print('1',p10_index, self.has_edge_been_handled[j,which_phi0-1])
                                e10ii = edgeii
                                e10 = edgei
                                j10 = j
                    #check if edge intersects interface theta
                    if phi1[edgeii[0]] * phi1[edgeii[1]] < 0:
                        pii1 = pii1 + 1
                        taue = -phi1[edgeii[0]]/(phi1[edgeii[1]] - phi1[edgeii[0]])
                        pe = (1-taue)*edge[0] + taue*edge[1]
                        #Delta stuff
                        e0_delta = taue > self.delta
                        e1_delta = taue < 1-self.delta
                        e0e1_delta = e0_delta and e1_delta
                        if any(Is_point_BP[edgeii,0] == 1) and not(all(Is_point_BP[edgeii,0] == 1)):
                            if Is_point_BP[edgeii[0],0] == 1 and not(e0_delta):
                                B_edge = True
                            elif Is_point_BP[edgeii[1],0] == 1 and not(e1_delta):
                                B_edge = True

                        if all(Is_point_BP[edgeii,0] == 1) and not(Is_point_BP[edgeii[0],1] == Is_point_BP[edgeii[1],1]) and all(Is_point_BP[edgeii,1] < 5):
                            B_edge = True

                        if any(Is_point_BP[edgeii,1] == 5):
                            if Is_point_BP[edgeii[0],1] == 5 and not(e0_delta):
                                B_edge = True
                            elif Is_point_BP[edgeii[1],1] == 5 and not(e1_delta):
                                B_edge = True
                        if which_phi1 == 2:
                            if self.has_point_been_shifted[edgeii[0],0] == 1 and not(e0_delta) and not(any(self.has_point_been_shifted[edgeii[0],1] == [2, 3])):
                                B_edge = True
                            elif self.has_point_been_shifted[edgeii[1],0] == 1  and not(e1_delta) and not(any(self.has_point_been_shifted[edgeii[1],1] == [2, 3])):
                                B_edge = True
                        else:
                            if self.has_point_been_shifted[edgeii[0],0] == 1 and not(e0_delta) and not(self.has_point_been_shifted[edgeii[0],1]%10 == which_phi1):
                                B_edge = True
                            elif self.has_point_been_shifted[edgeii[1],0] == 1  and not(e1_delta) and not(self.has_point_been_shifted[edgeii[1],1]%10 == which_phi1):
                                B_edge = True
                        if B_edge or e0e1_delta:
                            amount_new1 = amount_new1 + 1
                            amount_new_edge = amount_new_edge + 1
                            if self.has_edge_been_handled[j,which_phi1-1] == -1:
                                self.enriched_mesh.points = np.vstack((self.enriched_mesh.points,pe))
                                if not(any(edgeii > self.N)): #not(any(self.has_point_been_shifted[edgeii, 1]%4 == 0)):
                                    cut_Tau = np.zeros(self.background_mesh.n+1)
                                    cut_Tau[[edgeii]] = np.array([1-taue, taue])
                                    if self.background_mesh.Tau[edgeii[0], edgeii[0]] != 0:
                                        other_points = self.background_mesh.Tau[edgeii[0]].nonzero()[1]
                                        cut_Tau[edgeii[0]] = 0
                                        cut_Tau[[other_points]] = cut_Tau[[other_points]] + (1-taue) * self.background_mesh.Tau[edgeii[0], other_points].toarray()
                                    if self.background_mesh.Tau[edgeii[1], edgeii[1]] != 0:
                                        other_points = self.background_mesh.Tau[edgeii[1]].nonzero()[1]
                                        cut_Tau[edgeii[1]] = 0
                                        cut_Tau[[other_points]] = cut_Tau[[other_points]] + taue * self.background_mesh.Tau[edgeii[1], other_points].toarray()
                                    cut_Tau[self.background_mesh.n] = self.enriched_mesh.n
                                    self.background_mesh.Tau = vstack((self.background_mesh.Tau, cut_Tau), format = 'lil')

                                if which_phi1 == 1:
                                    phi_at_pe = self.level_set_alphatheta_enriched.interpolate(trii,tri,pe)
                                    self.level_set_gammaalpha_enriched.phi = np.append(self.level_set_gammaalpha_enriched.phi, 0)
                                    self.level_set_alphatheta_enriched.phi = np.append(self.level_set_alphatheta_enriched.phi, phi_at_pe)
                                    if phi_at_pe < 0:
                                        self.has_point_been_shifted = np.vstack((self.has_point_been_shifted, [1, 1]))
                                    else:
                                        self.has_point_been_shifted = np.vstack((self.has_point_been_shifted, [1, 11]))

                                elif which_phi1 == 2:
                                    phi_ga_pe = self.level_set_gammaalpha_enriched.interpolate(trii,tri,pe)
                                    if phi_ga_pe < 0:
                                        self.has_point_been_shifted = np.vstack((self.has_point_been_shifted, [1, 3]))
                                    else:
                                        self.has_point_been_shifted = np.vstack((self.has_point_been_shifted, [1, 2]))
                                    self.level_set_alphatheta_enriched.phi = np.append(self.level_set_alphatheta_enriched.phi, 0)
                                    self.level_set_gammaalpha_enriched.phi = np.append(self.level_set_gammaalpha_enriched.phi, phi_ga_pe)

                            if pii1 == 1:
                                p01 = pe
                                if self.has_edge_been_handled[j,which_phi1-1] == -1:
                                    p01_index = self.enriched_mesh.n
                                    self.enriched_mesh.n = self.enriched_mesh.n + 1
                                else:
                                    p01_index = self.has_edge_been_handled[j,which_phi1-1]
                                    if p01_index < self.N:
                                        print('0',p01_index, self.has_edge_been_handled[j,which_phi1-1])
                                e01ii =  edgeii
                                e01 = edgei
                                j01 = j
                            if pii1 == 2:
                                p11 = pe
                                if self.has_edge_been_handled[j,which_phi1-1] == -1:
                                    p11_index = self.enriched_mesh.n
                                    self.enriched_mesh.n = self.enriched_mesh.n + 1
                                else:
                                    p11_index = self.has_edge_been_handled[j,which_phi1-1]
                                    if p11_index < self.N:
                                        print('1',p11_index, self.has_edge_been_handled[j,which_phi1-1])
                                e11ii = edgeii
                                e11 = edgei
                                j11 = j
                    if amount_new_edge == 2:
                        j_two_cuts = j
                if pii0 + pii1 == 3:
                    print('cut_twice, pii0, pii1 ', pii0, pii1, 'trii \n', trii)
                    if pii0 == 1: #cut_twice 101
                        index_shift = np.setdiff1d(trii, e00ii)
                        index_cutoff = np.intersect1d(e01ii, e11ii)
                        if j00 == j01: #index_shift is opposite p01_index
                            trii0, trii1 = cGrid.least_angle_trii(self, index_shift, p00_index, p11_index, p01_index)
                        elif j00 == j11: #index_shift is opposite p11_index
                            trii0, trii1 = cGrid.least_angle_trii(self, index_shift, p00_index, p01_index, p11_index)
                        else:
                            print('cut_twice not cutting twice, trii, tri j00 j01 j11 pii0 pii1 \n', trii, tri, j00, j01, j11, pii0, pii1)
                            try:
                                print('j10 ', j10)
                            except:
                                print('no j10')
                        trii2 = np.hstack((np.setdiff1d(trii, index_cutoff), p00_index))
                        trii3 = np.hstack((index_cutoff, p01_index, p11_index))
                        self.enriched_mesh.edges_index = np.vstack((self.enriched_mesh.edges_index, np.hstack((index_shift, p00_index)), np.hstack((p01_index, p11_index))))
                        if trii0[0] == p00_index:
                            if j00 == j01 :
                                self.enriched_mesh.edges_index = np.vstack((self.enriched_mesh.edges_index, np.hstack((index_shift, p01_index))))
                            elif j00 == j11:
                                self.enriched_mesh.edges_index = np.vstack((self.enriched_mesh.edges_index, np.hstack((index_shift, p11_index))))
                        else:
                            if j00 == j01:
                                self.enriched_mesh.edges_index = np.vstack((self.enriched_mesh.edges_index, np.hstack((p00_index, p11_index))))
                            elif j00 == j11:
                                self.enriched_mesh.edges_index = np.vstack((self.enriched_mesh.edges_index, np.hstack((p00_index, p01_index))))
                        if self.has_edge_been_handled[j00,0] == -1:
                            self.enriched_mesh.edges_index[j00] = np.hstack((np.setdiff1d(trii, [index_shift, index_cutoff]), p00_index))
                            if j00 == j01:
                                self.enriched_mesh.edges_index = np.vstack((self.enriched_mesh.edges_index, np.hstack((index_cutoff, p01_index)), np.hstack((p00_index, p01_index))))
                            elif j00 == j11:
                                self.enriched_mesh.edges_index = np.vstack((self.enriched_mesh.edges_index, np.hstack((index_cutoff, p11_index)), np.hstack((p00_index, p11_index))))
                        if j00 == j01:
                            if self.has_edge_been_handled[j11,0] == -1:
                                self.enriched_mesh.edges_index = np.vstack((self.enriched_mesh.edges_index, np.hstack((index_cutoff, p11_index)), np.hstack((index_shift, p11_index))))
#                                self.has_edge_been_handled[j11,0] = p11_index
                        elif j00 == j11:
                            if self.has_edge_been_handled[j01,0] == -1:
                                self.enriched_mesh.edges_index = np.vstack((self.enriched_mesh.edges_index, np.hstack((index_cutoff, p01_index)), np.hstack((index_shift, p01_index))))
#                                self.has_edge_been_handled[j01,0] = p01_index

                        if j00 == j01:
                            self.has_edge_been_handled[j00] = np.hstack((p00_index, p01_index))
                            self.has_edge_been_handled[j11] = p11_index
                        elif j00 == j11:
                            self.has_edge_been_handled[j00] = np.hstack((p00_index, p11_index))
                            self.has_edge_been_handled[j01] = p01_index

                    if pii1 == 1: #cut_twice 101
                        index_shift = np.setdiff1d(trii, e01ii)
                        index_cutoff = np.intersect1d(e00ii, e10ii)
                        if j01 == j00: #index_shift is opposite p00_index
                            trii0, trii1 = cGrid.least_angle_trii(self, index_shift, p01_index, p10_index, p00_index)
                        elif j01 == j10: #index_shift is opposite p10_index
                            trii0, trii1 = cGrid.least_angle_trii(self, index_shift, p01_index, p00_index, p10_index)
                        else:
                            print('cut_twice not cutting twice, trii, tri ', trii, tri)
                        trii2 = np.hstack((np.setdiff1d(trii, index_cutoff), p01_index))
                        trii3 = np.hstack((index_cutoff, np.array([p00_index, p10_index])))
                        self.enriched_mesh.edges_index = np.vstack((self.enriched_mesh.edges_index, np.hstack((index_shift, p01_index)), np.hstack((p00_index, p10_index))))
                        if trii0[0] == p01_index:
                            if j01 == j00:
                                self.enriched_mesh.edges_index = np.vstack((self.enriched_mesh.edges_index, np.hstack((index_shift, p00_index))))
                            elif j01 == j10:
                                self.enriched_mesh.edges_index = np.vstack((self.enriched_mesh.edges_index, np.hstack((index_shift, p10_index))))
                        else:
                            if j01 == j00:
                                self.enriched_mesh.edges_index = np.vstack((self.enriched_mesh.edges_index, np.hstack((p01_index, p10_index))))
                            elif j01 == j10:
                                self.enriched_mesh.edges_index = np.vstack((self.enriched_mesh.edges_index, np.hstack((p01_index, p00_index))))
                        if self.has_edge_been_handled[j01,1] == -1:
                            self.enriched_mesh.edges_index[j01] = np.hstack((np.setdiff1d(trii, [index_shift, index_cutoff]), p01_index))
                            if j01 == j00:
                                self.enriched_mesh.edges_index = np.vstack((self.enriched_mesh.edges_index, np.hstack((index_cutoff, p00_index)), np.hstack((p01_index, p00_index))))
                            elif j01 == j10:
                                self.enriched_mesh.edges_index = np.vstack((self.enriched_mesh.edges_index, np.hstack((index_cutoff, p10_index)), np.hstack((p01_index, p10_index))))
                        if j01 == j00:
                            if self.has_edge_been_handled[j10,0] == -1:
                                self.enriched_mesh.edges_index = np.vstack((self.enriched_mesh.edges_index, np.hstack((index_cutoff, p10_index)), np.hstack((index_shift, p10_index))))
                        elif j01 == j10:
                            if self.has_edge_been_handled[j00,0] == -1:
                                self.enriched_mesh.edges_index = np.vstack((self.enriched_mesh.edges_index, np.hstack((index_cutoff, p00_index)), np.hstack((index_shift, p00_index))))

                        if j01 == j00:
                            self.has_edge_been_handled[j01] = np.hstack((p00_index, p01_index))
                            self.has_edge_been_handled[j10] = p10_index
                        elif j01 == j10:
                            self.has_edge_been_handled[j01] = np.hstack((p10_index, p01_index))
                            self.has_edge_been_handled[j00] = p00_index

                    self.enriched_mesh.triangles_points_index[which_tri[i]] = trii0
                    self.enriched_mesh.triangles_points_index = np.vstack((self.enriched_mesh.triangles_points_index,trii1, trii2, trii3))

                    self.enriched_mesh.n_tri = self.enriched_mesh.n_tri + 3

                elif pii0 + pii1 == 4:
                    #Two options, both cut in same edges or one edge has two cuts and other two have one
                    #First option:
                    if all(np.sort([j00, j10]) == np.sort([j01, j11])): #cut_twice 200 two edges
                        print('cut_twice two edges, pii0, pii1 ', pii0, pii1, 'trii \n', trii)
                        index_cutoff = np.intersect1d(e00ii, e10ii)
                        if la.norm(self.enriched_mesh.points[index_cutoff] - p01) < la.norm(self.enriched_mesh.points[index_cutoff] - p00):
                            xa = p01_index
                            xb = p11_index
                            xc = p00_index
                            xd = p10_index
                        else:
                            xa = p00_index
                            xb = p10_index
                            xc = p01_index
                            xd = p11_index
                        xbd = np.setdiff1d(e10ii, index_cutoff)
                        xac = np.setdiff1d(e00ii, index_cutoff)

                        self.enriched_mesh.triangles_points_index[which_tri[i]] = np.hstack((index_cutoff, xa, xb))
                        trii0, trii1 = cGrid.least_angle_trii(self, xa, xb, xc, xd)
                        trii2, trii3 = cGrid.least_angle_trii(self, xac, xbd, xc, xd)


                        self.enriched_mesh.triangles_points_index = np.vstack((self.enriched_mesh.triangles_points_index, trii0, trii1, trii2, trii3))

                        self.enriched_mesh.n_tri = self.enriched_mesh.n_tri + 4

                        if trii0[0] == xb: #first option
                            self.enriched_mesh.edges_index = np.vstack((self.enriched_mesh.edges_index, np.hstack((xb, xc))))
                        else:
                            self.enriched_mesh.edges_index = np.vstack((self.enriched_mesh.edges_index, np.hstack((xa, xd))))

                        if trii2[0] == xbd:
                            self.enriched_mesh.edges_index = np.vstack((self.enriched_mesh.edges_index, np.hstack((xbd, xc))))
                        else:
                            self.enriched_mesh.edges_index = np.vstack((self.enriched_mesh.edges_index, np.hstack((xac, xd))))

                        if self.has_edge_been_handled[j00,0] == -1:
                            self.enriched_mesh.edges_index[j00] = np.hstack((index_cutoff, xa))
                            self.enriched_mesh.edges_index = np.vstack((self.enriched_mesh.edges_index, np.hstack((xa, xc)), np.hstack((xac, xc))))
                        if self.has_edge_been_handled[j10,0] == -1:
                            self.enriched_mesh.edges_index[j10] = np.hstack((index_cutoff, xb))
                            self.enriched_mesh.edges_index = np.vstack((self.enriched_mesh.edges_index, np.hstack((xb, xd)), np.hstack((xbd, xd))))
                        self.enriched_mesh.edges_index = np.vstack((self.enriched_mesh.edges_index, np.hstack((xa, xb)), np.hstack((xc, xd))))
                        self.has_edge_been_handled[j00] = np.hstack([p00_index, p01_index])
                        self.has_edge_been_handled[j10] = np.hstack([p10_index, p11_index])

                    #Second option
                    else: #cut_twice 200 three edges
                        print('cut_twice, pii0, pii1 three edges ', pii0, pii1, 'trii \n', trii)
                        index_cutoff0 = np.intersect1d(e00ii, e10ii)[0]
                        index_cutoff1 = np.intersect1d(e01ii, e11ii)[0]
                        xb0b1 = np.setdiff1d(trii, np.hstack((index_cutoff0, index_cutoff1)))[0]
                        #a0 and a1 are always on the double cut edge
                        if j00 == j_two_cuts:
                            ja0 = j00
                            jb0 = j10
                            a0 = p00_index
                            b0 = p10_index
                        else:
                            ja0 = j10
                            jb0 = j00
                            a0 = p10_index
                            b0 = p00_index
                        if j01 == j_two_cuts:
                            ja1 = j01
                            jb1 = j11
                            a1 = p01_index
                            b1 = p11_index
                        else:
                            ja1 = j11
                            jb1 = j01
                            a1 = p11_index
                            b1 = p01_index
                        print('xb0b1, b0, b1, a0, a1 ',xb0b1, b0, b1, a0, a1)
                        trii0 = np.hstack((index_cutoff0, a0, b0))
                        trii1 = np.hstack((index_cutoff1, a1, b1))

                        trii2, trii3, trii4 = cGrid.least_angle_trii_5p(self, xb0b1, b0, b1, a0, a1)
                        self.enriched_mesh.triangles_points_index[which_tri[i]] = trii0
                        self.enriched_mesh.triangles_points_index = np.vstack((self.enriched_mesh.triangles_points_index, trii1, trii2, trii3, trii4))

                        self.enriched_mesh.n_tri = self.enriched_mesh.n_tri + 4

                        if trii4[0] == b1: #1st option
                            print('took 1st option')
                            self.enriched_mesh.edges_index = np.vstack((self.enriched_mesh.edges_index, np.hstack((a0, b1)) ))
                            if trii3[0] == b0:
                                self.enriched_mesh.edges_index = np.vstack((self.enriched_mesh.edges_index, np.hstack((b0, b1)) ))
                            else:
                                self.enriched_mesh.edges_index = np.vstack((self.enriched_mesh.edges_index, np.hstack((xb0b1, a0)) ))
                        elif trii4[0] == b0: #2nd option
                            print('took 2nd option')
                            self.enriched_mesh.edges_index = np.vstack((self.enriched_mesh.edges_index, np.hstack((a1, b0)) ))
                            if trii3[0] == b0:
                                self.enriched_mesh.edges_index = np.vstack((self.enriched_mesh.edges_index, np.hstack((b0, b1)) ))
                            else:
                                self.enriched_mesh.edges_index = np.vstack((self.enriched_mesh.edges_index, np.hstack((xb0b1, a1)) ))
                        elif trii4[0] == xb0b1: #third option
                            print('took 3rd option')
                            self.enriched_mesh.edges_index = np.vstack((self.enriched_mesh.edges_index, np.hstack((xb0b1, a1)) ))
                            if trii3[0] == b0:
                                self.enriched_mesh.edges_index = np.vstack((self.enriched_mesh.edges_index, np.hstack((b0, a1)) ))
                            else:
                                self.enriched_mesh.edges_index = np.vstack((self.enriched_mesh.edges_index, np.hstack((xb0b1, a1)) ))


                        if self.has_edge_been_handled[j_two_cuts,0] == -1:
                            self.enriched_mesh.edges_index[ja0] = np.hstack((index_cutoff0, a0))
                            self.enriched_mesh.edges_index = np.vstack((self.enriched_mesh.edges_index, np.hstack((a0, a1)), np.hstack((index_cutoff1, a1)) ))

                        if self.has_edge_been_handled[jb0,0] == -1:
                            self.enriched_mesh.edges_index[jb0] = np.hstack((index_cutoff0, b0))
                            self.enriched_mesh.edges_index = np.vstack((self.enriched_mesh.edges_index, np.hstack((xb0b1, b0))))

                        if self.has_edge_been_handled[jb1,1] == -1:
                            self.enriched_mesh.edges_index[jb1] = np.hstack((index_cutoff1, b1))
                            self.enriched_mesh.edges_index = np.vstack((self.enriched_mesh.edges_index, np.hstack((xb0b1, b1))))
                        self.enriched_mesh.edges_index = np.vstack((self.enriched_mesh.edges_index, np.hstack((a0, b0)), np.hstack((a1, b1)) ))
                        self.has_edge_been_handled[j00,0] = p00_index
                        self.has_edge_been_handled[j10,0] = p10_index
                        self.has_edge_been_handled[j01,1] = p01_index
                        self.has_edge_been_handled[j11,1] = p11_index
                #It can be two if other two points cut in triple
                elif pii0 + pii1 == 2:
                    print('cut twice, pii0, pii1 one edge ', pii0, pii1, 'trii \n', trii)
                    if pii0 == 2:
                        x_ga_index = np.setdiff1d(trii, e00ii)
                        dist_e000_p00 = la.norm(p00 - self.enriched_mesh.points[e00ii[0]], 2)
                        dist_e000_p01 = la.norm(p10 - self.enriched_mesh.points[e00ii[0]], 2)
                        if dist_e000_p00 > dist_e000_p01:
                            index_cutoff0 = e00ii[1]
                            index_cutoff1 = e00ii[0]
                        elif dist_e000_p00 < dist_e000_p01:
                            index_cutoff0 = e00ii[0]
                            index_cutoff1 = e00ii[1]
                        else:
                            print('same points on e00ii')
                        trii0 = np.hstack((index_cutoff0, x_ga_index, p00_index))
                        trii1 = np.hstack((index_cutoff1, x_ga_index, p01_index))
                        trii2 = np.hstack((x_ga_index, p00_index, p01_index))


                        self.enriched_mesh.triangles_points_index[which_tri[i]] = trii0
                        self.enriched_mesh.triangles_points_index = np.vstack((self.enriched_mesh.triangles_points_index, trii1, trii2))

                        if self.has_edge_been_handled[j_two_cuts,0] == -1:
                            self.enriched_mesh.edges_index[j_two_cuts] = np.hstack((index_cutoff0, p00_index))
                            self.enriched_mesh.edges_index = np.vstack((self.enriched_mesh.edges_index, np.hstack((index_cutoff1, p01_index)), np.hstack((p00_index, p01_index)) ))
                        self.enriched_mesh.edges_index = np.vstack((self.enriched_mesh.edges_index, np.hstack((x_ga_index, p00_index)), np.hstack((x_ga_index, p01_index)) ))
                        self.has_edge_been_handled[j_two_cuts] = np.hstack((p00_index, p01_index))

                        self.enriched_mesh.n_tri = self.enriched_mesh.n_tri + 2
                    elif pii1 == 2:
                        x_ga_index = np.setdiff1d(trii, e01ii)
                        dist_e000_p00 = la.norm(p01 - self.enriched_mesh.points[e01ii[0]], 2)
                        dist_e000_p01 = la.norm(p11 - self.enriched_mesh.points[e01ii[0]], 2)
                        if dist_e000_p00 > dist_e000_p01:
                            index_cutoff0 = e01ii[1]
                            index_cutoff1 = e01ii[0]
                        elif dist_e000_p00 < dist_e000_p01:
                            index_cutoff0 = e01ii[0]
                            index_cutoff1 = e01ii[1]
                        else:
                            print('same points on e00ii')
                        trii0 = np.hstack((index_cutoff0, x_ga_index, p00_index))
                        trii1 = np.hstack((index_cutoff1, x_ga_index, p01_index))
                        trii2 = np.hstack((x_ga_index, p00_index, p01_index))


                        self.enriched_mesh.triangles_points_index[which_tri[i]] = trii0
                        self.enriched_mesh.triangles_points_index = np.vstack((self.enriched_mesh.triangles_points_index, trii1, trii2))

                        if self.has_edge_been_handled[j_two_cuts,0] == -1:
                            self.enriched_mesh.edges_index[j_two_cuts] = np.hstack((index_cutoff0, p00_index))
                            self.enriched_mesh.edges_index = np.vstack((self.enriched_mesh.edges_index, np.hstack((index_cutoff1, p01_index)), np.hstack((p00_index, p01_index)) ))
                        self.enriched_mesh.edges_index = np.vstack((self.enriched_mesh.edges_index, np.hstack((x_ga_index, p00_index)), np.hstack((x_ga_index, p01_index)) ))
                        self.has_edge_been_handled[j_two_cuts] = np.hstack((p00_index, p01_index))

                        self.enriched_mesh.n_tri = self.enriched_mesh.n_tri + 2
                    else:
                        x_ga_index = np.setdiff1d(trii, e00ii)
                        dist_e000_p00 = la.norm(p00 - self.enriched_mesh.points[e00ii[0]], 2)
                        dist_e000_p01 = la.norm(p01 - self.enriched_mesh.points[e00ii[0]], 2)
                        if dist_e000_p00 < dist_e000_p01:
                            index_cutoff0 = e00ii[0]
                            index_cutoff1 = e00ii[1]
                        elif dist_e000_p00 > dist_e000_p01:
                            index_cutoff0 = e00ii[1]
                            index_cutoff1 = e00ii[0]
                        else:
                            print('same points on e00ii')

                        trii0 = np.hstack((index_cutoff0, x_ga_index, p00_index))
                        trii1 = np.hstack((index_cutoff1, x_ga_index, p01_index))
                        trii2 = np.hstack((x_ga_index, p00_index, p01_index))

                        self.enriched_mesh.triangles_points_index[which_tri[i]] = trii0
                        self.enriched_mesh.triangles_points_index = np.vstack((self.enriched_mesh.triangles_points_index, trii1, trii2))

                        if self.has_edge_been_handled[j00,0] == -1:
                            self.enriched_mesh.edges_index[j00] = np.hstack((index_cutoff0, p00_index))
                            self.enriched_mesh.edges_index = np.vstack((self.enriched_mesh.edges_index, np.hstack((index_cutoff1, p01_index)), np.hstack((p00_index, p01_index)) ))
                        self.enriched_mesh.edges_index = np.vstack((self.enriched_mesh.edges_index, np.hstack((x_ga_index, p00_index)), np.hstack((x_ga_index, p01_index)) ))

                        self.has_edge_been_handled[j00] = np.hstack((p00_index, p01_index))

                        self.enriched_mesh.n_tri = self.enriched_mesh.n_tri + 2


    ### For reinitialization we need the position of the interface points from the background mesh, we can find these points with the tau values    
    def update_Tau_all(self, new_ga, new_t):
        if new_ga + new_t > 0:
            if new_ga == 1:
                self.background_mesh.Tau_all_ga = coo_matrix((0, self.background_mesh.n))
                tau_ga_done = lil_matrix((self.background_mesh.n_edges,1), dtype = np.int)
            if new_t == 1:
                self.background_mesh.Tau_all_t  = coo_matrix((0, self.background_mesh.n))
                tau_t_done  = lil_matrix((self.background_mesh.n_edges,1), dtype = np.int)

            phi_ga = self.level_set_gammaalpha_enriched.phi_background
            phi_at = self.level_set_alphatheta_enriched.phi_background
            for trii in self.background_mesh.triangles_points_index:
                tri = self.background_mesh.points[trii]
                for edgei in np.array([[0,1],[0,2],[1,2]]):
                    edgeii_sorted = np.sort(trii[edgei])
                    edgeii = trii[edgei]
                    j = self.background_mesh.edge_to_index[edgeii_sorted[0], edgeii_sorted[1]]
                    edge = tri[edgei]
                    ga_tri = phi_ga[edgeii[0]] * phi_ga[edgeii[1]] < 0
                    at_tri = phi_at[edgeii[0]] * phi_at[edgeii[1]] < 0
                    if at_tri and new_t == 1:
                        taue_at = -phi_at[edgeii[0]]/(phi_at[edgeii[1]] - phi_at[edgeii[0]])
                        row = np.zeros(2, dtype = np.int)
                        col = edgeii
                        data = np.array([1-taue_at, taue_at])
                        shift_cut_tau = coo_matrix( (data, (row,col)), shape = (1, self.background_mesh.n))
                        if tau_t_done[j,0] == 0:
                            self.background_mesh.Tau_all_t = vstack((self.background_mesh.Tau_all_t, shift_cut_tau))
                        tau_t_done[j] = 1
                    if ga_tri and new_ga == 1:# and any(self.level_set_alphatheta_enriched.phi_background[edgeii] < 0):
                        taue_ga = -phi_ga[edgeii[0]]/(phi_ga[edgeii[1]] - phi_ga[edgeii[0]])
                        row = np.zeros(2, dtype = np.int)
                        col = edgeii
                        data = np.array([1-taue_ga, taue_ga])
                        shift_cut_tau = coo_matrix( (data, (row, col)), shape = (1, self.background_mesh.n))
                        if tau_ga_done[j,0] == 0:
                            self.background_mesh.Tau_all_ga = vstack((self.background_mesh.Tau_all_ga, shift_cut_tau))
                        tau_ga_done[j] = 1
            self.background_mesh.Tau_all_t = self.background_mesh.Tau_all_t.tocsr()
            if self.two_particles == None and self.background_mesh.i_ghost_fixed != -1:
                fixed_point_Tau = np.zeros(self.background_mesh.n)
                fixed_point_Tau[self.background_mesh.i_ghost_fixed] = 1
                self.background_mesh.Tau_all_ga = vstack((self.background_mesh.Tau_all_ga, fixed_point_Tau))
            self.background_mesh.Tau_all_ga = self.background_mesh.Tau_all_ga.tocsr()

    # Function to filter out double elements of a vector containing elements with two values.
    def unique_rows(a):
        a = np.ascontiguousarray(a)
        unique_a = np.unique(a.view([('', a.dtype)]*a.shape[1]))
        return unique_a.view(a.dtype).reshape((unique_a.shape[0], a.shape[1]))

    # Function to calculate area of triangle
    def area(triangle):
        p0 = triangle[0]
        p1 = triangle[1]
        p2 = triangle[2]
        a = np.linalg.norm(p0-p1) #np.sqrt((p0[0]-p1[0])**2 + (p0[1]-p1[1])**2)
        b = np.linalg.norm(p1-p2) #np.sqrt((p1[0]-p2[0])**2 + (p1[1]-p2[1])**2)
        c = np.linalg.norm(p2-p0) #np.sqrt((p2[0]-p0[0])**2 + (p2[1]-p0[1])**2)

        s = (a + b + c)/2.0

        Delta = (p1[0] - p0[0])*(p2[1] - p0[1]) - (p1[1] - p0[1])*(p2[0] - p0[0])

        if np.abs(np.abs(Delta/2) - np.sqrt(s*(s-a)*(s-b)*(s-c))) > 1e-10:
            print('Warning: Delta/2 is not same as area. Delta/2 is:',(Delta/2),'area is:', np.sqrt(s*(s-a)*(s-b)*(s-c)))
        return Delta/2

    def interpolate(phi, trii, tri, p):
        p0 = tri[0]
        p1 = tri[1]
        p2 = tri[2]
        Delta = ((p1[0] - p0[0])*(p2[1] - p0[1]) - (p1[1] - p0[1])*(p2[0] - p0[0]))

        b0 = (p1[1] - p2[1])/Delta
        b1 = (p2[1] - p0[1])/Delta
        b2 = (p0[1] - p1[1])/Delta

        g0 = (p2[0] - p1[0])/Delta
        g1 = (p0[0] - p2[0])/Delta
        g2 = (p1[0] - p0[0])/Delta

        a0 = 1 - b0*p0[0] - g0*p0[1]
        a1 = 1 - b1*p1[0] - g1*p1[1]
        a2 = 1 - b2*p2[0] - g2*p2[1]

        psi = np.zeros(3)
        psi[0] = a0 + b0*p[0] + g0*p[1]
        psi[1] = a1 + b1*p[0] + g1*p[1]
        psi[2] = a2 + b2*p[0] + g2*p[1]

        if any(psi > 1) or any(psi < 0):
            where_bad1, = np.where(psi > 1)
            where_bad0, = np.where(psi < 0)
            if any(psi[where_bad1]-1 > 1e-12) or any(np.abs(psi[where_bad0]) > 1e-12):
                print('interpolate in cGrid outside of this triangle, ',trii , 'psi ', psi)

        return phi[trii] @ psi




