Identify point to a DOF - Source drive

Hi,

I am trying to define a source at a specific vertice of the mesh grid. How can I identify a specific point (x,y,z) to set a specific coefficient (e.g., 1.0+1j*0.0)?

bempp.api.GridFunction(div_space, coefficients=coefficients, dual_space=curl_space)

This is the code I have until now:

# Source driven - The DOFs of RWG and SNC spaces are at the midpoints of the edges of each cell.
# Point (vertice) to identify
pointV1 = [-0.25*OperationWavelengthPA, 0.0*OperationWavelengthPA, 0.0*OperationWavelengthPA]
#Get points
pointInd=[] # A list because maybe more than one point is found
for i in np.arange(0,grid.number_of_edges,1):
  e=grid.edges[0,i]
  V1axis=np.abs(grid.vertices[:, e]-pointV1)
  DiffPoint1=np.sqrt(V1axis[0]**2+V1axis[1]**2+V1axis[2]**2)
  e=grid.edges[1,i]
  V2axis=np.abs(grid.vertices[:, e]-pointV1)
  DiffPoint2=np.sqrt(V2axis[0]**2+V2axis[1]**2+V2axis[2]**2)
  if (DiffPoint1<1.0*GridSizeh and DiffPoint2<1.0*GridSizeh):
    pointInd.append(i)
print('pointInd: '+str(pointInd))
# Get DOF
dof=[]
"""
dof=pointInd
for iIter in range(0,len(pointInd),1):
  for edges, dofs in zip(grid.edges, div_space.local2global): 
    for e, d in zip(edges, dofs): 
      if e == pointInd[iIter]: 
        dof[iIter] = d
"""
#Set-Up Coefficients
for iIter in range(0,len(pointInd),1):
  for edges, dofs in zip(grid.element_edges.T, div_space.local2global):#, div_space.local_multipliers): 
    for i, e in enumerate(edges):
      if (e == pointInd[iIter]):
        dof.append(dofs[i])

print('dof: '+str(dof))

Improved code

# Study how to identify DOFs for coefficient excitation
pointV1 = [0.0*OperationWavelengthPA, 0.25*OperationWavelengthPA, 0.0*OperationWavelengthPA]
# DOF: Degree of freedom; are the points in the middle of the grid triangular-mesh-edges which the excitation coefficients are set.
# In particular, might be of interst to set coefficient for the three DOFs in the grid cells of a RWC/SNC space
# Point to identify the closest edge. The closest edge is the one that has the two vertices closest to the point of interest
pointV1aux=pointV1
gridAux=grid
div_spaceAux=div_space
GridSizehAux=GridSizeh
def BemppIdentifyDOFcellsFromPoint(pointV1aux,gridAux,div_spaceAux,GridSizehAux,CelldofAux=False):
  ## Seems better for coefficient excitation to excite a single edge, and correspondingly its DOF. Variable CelldofAux=False identifies the closests edge DOF. Variable CelldofAux=True identifies the cells DOFs
  #Get edges
  EdgeInd=[] # Number identifying the edge number. A list because maybe more than one point is found
  v1EdgeInd=[] # List of vertice 1
  v2EdgeInd=[] # List of vertice 2
  Diff1EdgeInd=[] # List of distances of vertice 1
  Diff2EdgeInd=[] # List of distances of vertice 2
  for i in np.arange(0,gridAux.number_of_edges,1): # First identify a few candidate edges
    v1=gridAux.edges[0,i] # vertice 1 of the edge
    V1axis=np.abs(gridAux.vertices[:, v1]-pointV1aux)
    DiffPoint1=np.sqrt(V1axis[0]**2+V1axis[1]**2+V1axis[2]**2)
    v2=gridAux.edges[1,i] # vertice 2 of the edge
    V2axis=np.abs(gridAux.vertices[:, v2]-pointV1aux)
    DiffPoint2=np.sqrt(V2axis[0]**2+V2axis[1]**2+V2axis[2]**2)
    #if (DiffPoint1<1.5*GridSizehAux and DiffPoint2<1.5*GridSizehAux):
    EdgeInd.append(i)
    Diff1EdgeInd.append(DiffPoint1)
    Diff2EdgeInd.append(DiffPoint2)
    v1EdgeInd.append(gridAux.vertices[:, v1])
    v2EdgeInd.append(gridAux.vertices[:, v2])
  # Order from minimum distance (the sum of the two distances between the two vertices of the edge) to maximum distance the identified edges
  EdgeInd=np.array(EdgeInd)# Convert to numpy array
  v1EdgeInd=np.array(v1EdgeInd)# Convert to numpy array
  v2EdgeInd=np.array(v2EdgeInd)# Convert to numpy array
  Diff1EdgeInd=np.array(Diff1EdgeInd)# Convert to numpy array
  Diff2EdgeInd=np.array(Diff2EdgeInd)# Convert to numpy array
  TotalDiffEdgeInd=Diff1EdgeInd+Diff2EdgeInd # Total distance of the edge vertices to the point
  OrderIndicesEdgeInd=np.argsort(TotalDiffEdgeInd)
  OrderedMinEdgeIndPot=EdgeInd[OrderIndicesEdgeInd]
  OrderedMinv1EdgeIndPot=v1EdgeInd[OrderIndicesEdgeInd]
  OrderedMinv2EdgeIndPot=v2EdgeInd[OrderIndicesEdgeInd]
  OrderedMinDiff1EdgeIndPot=Diff1EdgeInd[OrderIndicesEdgeInd]
  OrderedMinDiff2EdgeIndPot=Diff2EdgeInd[OrderIndicesEdgeInd]
  # Consider the first two edges as the rulers. Now, order the other edges that share vertices
  # Find the common vertices of the first two edges, and then find the opposite vertices that the third edge should have
  OrderedMinEdgeInd=np.zeros_like(OrderedMinEdgeIndPot)
  OrderedMinv1EdgeInd=np.zeros_like(OrderedMinv1EdgeIndPot)
  OrderedMinv2EdgeInd=np.zeros_like(OrderedMinv2EdgeIndPot)
  OrderedMinDiff1EdgeInd=np.zeros_like(OrderedMinDiff1EdgeIndPot)
  OrderedMinDiff2EdgeInd=np.zeros_like(OrderedMinDiff2EdgeIndPot)
  if (CelldofAux):
    OrderedMinEdgeInd[0:2]=OrderedMinEdgeIndPot[0:2]
    OrderedMinv1EdgeInd[:,0:2]=OrderedMinv1EdgeIndPot[:,0:2]
    OrderedMinv2EdgeInd[:,0:2]=OrderedMinv2EdgeIndPot[:,0:2]
    OrderedMinDiff1EdgeInd[0:2]=OrderedMinDiff1EdgeIndPot[0:2]
    OrderedMinDiff2EdgeInd[0:2]=OrderedMinDiff2EdgeIndPot[0:2]

    v1a=gridAux.edges[0,OrderedMinEdgeInd[0]] # vertice a of edge 1
    v1b=gridAux.edges[1,OrderedMinEdgeInd[0]] # vertice b of edge 1
    v2a=gridAux.edges[0,OrderedMinEdgeInd[1]] # vertice a of edge 2
    v2b=gridAux.edges[1,OrderedMinEdgeInd[1]] # vertice b of edge 2
    if (v1a==v2a):
      v3a=v1b
      v3b=v2b
    elif(v1a==v2b):
      v3a=v1b
      v3b=v2a
    elif(v1b==v2a):
      v3a=v1a
      v3b=v2b
    else: # v1b==v2b
      v3a=v1a
      v3b=v2a
    # Find the third edge
    Edge3Ind=0
    for iIter in range(2,len(OrderedMinEdgeInd),1):
      if (((v3a==gridAux.edges[0,OrderedMinEdgeIndPot[iIter]]).all() and (v3b==gridAux.edges[1,OrderedMinEdgeIndPot[iIter]]).all() ) or ((v3b==gridAux.edges[0,OrderedMinEdgeIndPot[iIter]]).all()  and (v3a==gridAux.edges[1,OrderedMinEdgeIndPot[iIter]]).all() )):
        Edge3Ind=iIter
    OrderedMinEdgeInd[2]=OrderedMinEdgeIndPot[Edge3Ind]
    OrderedMinv1EdgeInd[2,:]=OrderedMinv1EdgeIndPot[Edge3Ind,:]
    OrderedMinv2EdgeInd[2,:]=OrderedMinv2EdgeIndPot[Edge3Ind,:]
    OrderedMinDiff1EdgeInd[2]=OrderedMinDiff1EdgeIndPot[Edge3Ind]
    OrderedMinDiff2EdgeInd[2]=OrderedMinDiff2EdgeIndPot[Edge3Ind]
    # Find a fourth edge, following the min distance criterion
    if (Edge3Ind==2):
      OrderedMinEdgeInd[3]=OrderedMinEdgeIndPot[3]
      OrderedMinv1EdgeInd[3,:]=OrderedMinv1EdgeIndPot[3,:]
      OrderedMinv2EdgeInd[3,:]=OrderedMinv2EdgeIndPot[3,:]
      OrderedMinDiff1EdgeInd[3]=OrderedMinDiff1EdgeIndPot[3]
      OrderedMinDiff2EdgeInd[3]=OrderedMinDiff2EdgeIndPot[3]
    else:
      OrderedMinEdgeInd[3]=OrderedMinEdgeIndPot[2]
      OrderedMinv1EdgeInd[3,:]=OrderedMinv1EdgeIndPot[2,:]
      OrderedMinv2EdgeInd[3,:]=OrderedMinv2EdgeIndPot[2,:]
      OrderedMinDiff1EdgeInd[3]=OrderedMinDiff1EdgeIndPot[2]
      OrderedMinDiff2EdgeInd[3]=OrderedMinDiff2EdgeIndPot[2]
    #print('OrderedMinEdgeInd: '+str(OrderedMinEdgeInd))
    # Should take the first three edges, that normally define a cell. In can happen that the point of inteest falls in and edge or vertice (then this situation should be handled)
    # But take the first six edges, because usually at the grid border less dofs are identified
    NpotentialEdges=4
    EdgeIndCell=OrderedMinEdgeInd[0:NpotentialEdges]
    v1IndCell=OrderedMinv1EdgeInd[0:NpotentialEdges]
    v2IndCell=OrderedMinv2EdgeInd[0:NpotentialEdges]
    EdgeDiff1IndCell=OrderedMinDiff1EdgeInd[0:NpotentialEdges]
    EdgeDiff2IndCell=OrderedMinDiff2EdgeInd[0:NpotentialEdges]
    # Checks
    if (np.sum(EdgeDiff1IndCell==0.0)>0 or np.sum(EdgeDiff2IndCell==0.0)>0): # Hit vertice
      print("Vertice hit. It should be dealt a side!")
    DotProdArray1=np.zeros((3),dtype=np.float32)
    DotProdArray2=np.zeros((3),dtype=np.float32)
    AbsProdArray1=np.zeros((3),dtype=np.float32)
    AbsProdArray2=np.zeros((3),dtype=np.float32)
    for iIter in range(0,3,1):
      DotProdArray1[iIter]=np.abs(np.dot(pointV1aux-v1IndCell[iIter],v2IndCell[iIter]-v1IndCell[iIter]))
      DotProdArray2[iIter]=np.abs(np.dot(pointV1aux-v2IndCell[iIter],v2IndCell[iIter]-v1IndCell[iIter]))
      AbsProdArray1[iIter]=np.sqrt((pointV1aux[0]-v1IndCell[iIter,0])**2+(pointV1aux[1]-v1IndCell[iIter,1])**2+(pointV1aux[2]-v1IndCell[iIter,2])**2)*np.sqrt((v2IndCell[iIter,0]-v1IndCell[iIter,0])**2+(v2IndCell[iIter,1]-v1IndCell[iIter,1])**2+(v2IndCell[iIter,2]-v1IndCell[iIter,2])**2)
      AbsProdArray2[iIter]=np.sqrt((pointV1aux[0]-v2IndCell[iIter,0])**2+(pointV1aux[1]-v2IndCell[iIter,1])**2+(pointV1aux[2]-v2IndCell[iIter,2])**2)*np.sqrt((v2IndCell[iIter,0]-v1IndCell[iIter,0])**2+(v2IndCell[iIter,1]-v1IndCell[iIter,1])**2+(v2IndCell[iIter,2]-v1IndCell[iIter,2])**2)
    # Probably now hitting an edge is well dealt
    #if (np.sum(DotProdArray1==AbsProdArray1)>0 or np.sum(DotProdArray2==AbsProdArray2)>0): # Hit edge
    #  print("Edge hit. It should be dealt a side!")
    # Get DOF
  else:
    EdgeIndCell=OrderedMinEdgeIndPot[0:1]
    v1IndCell=OrderedMinv1EdgeIndPot[0:1]
    v2IndCell=OrderedMinv2EdgeIndPot[0:1]
    EdgeDiff1IndCell=OrderedMinDiff1EdgeIndPot[0:1]
    EdgeDiff2IndCell=OrderedMinDiff2EdgeIndPot[0:1]
  
  Potentialdof=[]
  """
  dofAux=pointInd
  for iIter in range(0,len(EdgeIndCell),1):
    for edges, dofs in zip(gridAux.edges, div_spaceAux.local2global): 
      for e, d in zip(edges, dofs): 
        if e == EdgeIndCell[iIter]: 
          dof[iIter] = d
  """
  #Set-Up Coefficients
  for iIter in range(0,len(EdgeIndCell),1):
    for edges, dofs in zip(gridAux.element_edges.T, div_spaceAux.local2global):#, div_spaceAux.local_multipliers): 
      for i, e in enumerate(edges):
        if (e == EdgeIndCell[iIter]):
          Potentialdof.append(dofs[i])
  if (CelldofAux): # DOFs forming a cell
    dofAux = ([*set(Potentialdof)])[0:3] # Remove duplicate DOFs from the list, and consider the first three dofs (to form a cell)
  else: # DOF of the closest edge
    dofAux = [([*set(Potentialdof)])[0]] # Remove duplicate DOFs from the list, and consider only the first dofs (of an edge)
  print('dof: '+str(dofAux))
  return dofAux

dof=BemppIdentifyDOFcellsFromPoint(pointV1,grid,div_space,GridSizeh,False)