parameters: (sensors, paraDX=1, paraDepth=0, paraBoundary=2,
                        paraMaxCellSize=0.0, boundary=-1, boundaryMaxCellSize=0,
                        balanceDepth=True,
                        isClosed=False, addNodes=1, **kwargs)
return_statement: return poly
docstring: Create a PLC mesh for an inversion parameter mesh.
  
      Create a PLC mesh for an inversion parameter mesh with for a given list of
      sensor positions. Sensor positions are assumed to be on the surface and
      must be sorted and unique.
  
      You can create a parameter mesh without sensors if you just set [xMin,
      xMax] as sensors.
  
      The PLC is a :gimliapi:`GIMLI::Mesh` and contain nodes, edges and two
      region markers, one for the parameters domain (marker=2) and a larger
      boundary around the outside (marker=1)
  
      TODO:
          * additional topographic points
          * spline interpolation between sensorpoints or addpoints for non closed
          * subsurface sensors (partly .. see example)
  
      Parameters
      ----------
      sensors : [RVector3] | DataContainer with sensorPositions() | [xMin, xMax]
          Sensor positions. Must be sorted and unique in positive x direction.
          Depth need to be y-coordinate.
  
      paraDX : float [1]
          Relative distance for refinement nodes between two sensors (1=none),
          e.g., 0.5 means 1 additional node between two neighboring sensors
          e.g., 0.33 means 2 additional equidistant nodes between two sensors
  
      paraDepth : float, optional
          Maximum depth for parametric domain, 0 (default) means 0.4 * maximum
          sensor range.
  
      balanceDepth: bool [True]
          Equal depth for the parametric domain.
  
      paraBoundary : float, optional
          Margin for parameter domain in absolute sensor distances. 2 (default).
  
      paraMaxCellSize: double, optional
          Maximum size for parametric size in m*m
  
      boundaryMaxCellSize: double, optional
          Maximum cells size in the boundary region in m*m
  
      boundary : float, optional
          Boundary width to be appended for domain prolongation in absolute
          para domain width.
          Values lover 0 force the boundary to be 4 times para domain width.
  
      isClosed : bool [False]
          Create a closed geometry from sensor positions.
          Region marker is 1. Boundary marker is -1 (homogeneous Neumann)
  
      addNodes : int [1]
          Number of additional nodes to be added equidistant between sensors.
  
      Returns
      -------
      poly: :gimliapi:`GIMLI::Mesh`
          Piecewise linear complex (PLC) containing nodes and edges
  
      Examples
      --------
      >>> # no need to import matplotlib, pygimli show does.
      >>> import pygimli as pg
      >>> import pygimli.meshtools as plc
      >>> # Create the simplest paramesh PLC with a para box of 10 m without
      >>> # sensors
      >>> p = plc.createParaMeshPLC([0,10])
      >>> # you can add subsurface sensors now with
      >>> for z in range(1,4):
      ...     n = p.createNode((5,-z), -99)
      >>> ax,_ = pg.show(p)
docstring_summary: Create a PLC mesh for an inversion parameter mesh.
docstring_tokens: Create a PLC mesh for an inversion parameter mesh .
function: def createParaMeshPLC(sensors, paraDX=1, paraDepth=0, paraBoundary=2,
                        paraMaxCellSize=0.0, boundary=-1, boundaryMaxCellSize=0,
                        balanceDepth=True,
                        isClosed=False, addNodes=1, **kwargs):
      """Create a PLC mesh for an inversion parameter mesh.
  
      Create a PLC mesh for an inversion parameter mesh with for a given list of
      sensor positions. Sensor positions are assumed to be on the surface and
      must be sorted and unique.
  
      You can create a parameter mesh without sensors if you just set [xMin,
      xMax] as sensors.
  
      The PLC is a :gimliapi:`GIMLI::Mesh` and contain nodes, edges and two
      region markers, one for the parameters domain (marker=2) and a larger
      boundary around the outside (marker=1)
  
      TODO:
          * additional topographic points
          * spline interpolation between sensorpoints or addpoints for non closed
          * subsurface sensors (partly .. see example)
  
      Parameters
      ----------
      sensors : [RVector3] | DataContainer with sensorPositions() | [xMin, xMax]
          Sensor positions. Must be sorted and unique in positive x direction.
          Depth need to be y-coordinate.
  
      paraDX : float [1]
          Relative distance for refinement nodes between two sensors (1=none),
          e.g., 0.5 means 1 additional node between two neighboring sensors
          e.g., 0.33 means 2 additional equidistant nodes between two sensors
  
      paraDepth : float, optional
          Maximum depth for parametric domain, 0 (default) means 0.4 * maximum
          sensor range.
  
      balanceDepth: bool [True]
          Equal depth for the parametric domain.
  
      paraBoundary : float, optional
          Margin for parameter domain in absolute sensor distances. 2 (default).
  
      paraMaxCellSize: double, optional
          Maximum size for parametric size in m*m
  
      boundaryMaxCellSize: double, optional
          Maximum cells size in the boundary region in m*m
  
      boundary : float, optional
          Boundary width to be appended for domain prolongation in absolute
          para domain width.
          Values lover 0 force the boundary to be 4 times para domain width.
  
      isClosed : bool [False]
          Create a closed geometry from sensor positions.
          Region marker is 1. Boundary marker is -1 (homogeneous Neumann)
  
      addNodes : int [1]
          Number of additional nodes to be added equidistant between sensors.
  
      Returns
      -------
      poly: :gimliapi:`GIMLI::Mesh`
          Piecewise linear complex (PLC) containing nodes and edges
  
      Examples
      --------
      >>> # no need to import matplotlib, pygimli show does.
      >>> import pygimli as pg
      >>> import pygimli.meshtools as plc
      >>> # Create the simplest paramesh PLC with a para box of 10 m without
      >>> # sensors
      >>> p = plc.createParaMeshPLC([0,10])
      >>> # you can add subsurface sensors now with
      >>> for z in range(1,4):
      ...     n = p.createNode((5,-z), -99)
      >>> ax,_ = pg.show(p)
      """
      if isClosed:
          plc = createPolygon(sensors, isClosed=True, addNodes=addNodes,
                              boundaryMarker=-1, marker=1,
                              area=paraMaxCellSize, **kwargs)
          return plc
  
      noSensors = False
      if hasattr(sensors, 'sensorPositions'):  # obviously a DataContainer type
          sensors = sensors.sensorPositions()
      elif isinstance(sensors, np.ndarray):
          if sensors.ndim == 1:
              sensors = [pg.RVector3(s, 0) for s in sensors]
          else:  # assume 2d array with 2 or 3 values per item
              sensors = [pg.RVector3(s) for s in sensors]
      elif isinstance(sensors, list):
          if len(sensors) == 2:
              # guess we have just a desired Pbox with
              sensors = [pg.RVector3(sensors[0], 0.0),
                         pg.RVector3(sensors[1], 0.0)]
              noSensors = True
              paraBoundary = 0
  
      eSpacing = kwargs.pop('eSpacing', sensors[0].distance(sensors[1]))
  
      iz = 1
      xMin, yMin, zMin = sensors[0][0], sensors[0][1], sensors[0][2]
      xMax, yMax, zMax = xMin, yMin, zMin
      for e in sensors:
          xMin = min(xMin, e[0])
          xMax = max(xMax, e[0])
          yMin = min(yMin, e[1])
          yMax = max(yMax, e[1])
          zMin = min(zMin, e[2])
          zMax = max(zMax, e[2])
  
      if abs(yMin) < 1e-8 and abs(yMax) < 1e-8:
          iz = 2
  
      paraBound = eSpacing * paraBoundary
  
      if paraDepth == 0:
          paraDepth = 0.4 * (xMax - xMin)
  
      poly = pg.Mesh(dim=2, isGeometry=True)
      # define para domain without surface
      n1 = poly.createNode([xMin - paraBound, sensors[0][iz]])
      if balanceDepth:
          bD = min(sensors[0][iz] - paraDepth, sensors[0][iz] - paraDepth)
          n2 = poly.createNode([xMin - paraBound, bD])
          n3 = poly.createNode([xMax + paraBound, bD])
      else:
          n2 = poly.createNode([xMin - paraBound, sensors[0][iz] - paraDepth])
          n3 = poly.createNode([xMax + paraBound, sensors[-1][iz] - paraDepth])
      n4 = poly.createNode([xMax + paraBound, sensors[-1][iz]])
  
      if boundary < 0:
          boundary = 4
  
      bound = abs(xMax - xMin) * boundary
      if bound > paraBound:
          # define world without surface
          n11 = poly.createNode(n1.pos() - [bound, 0.])
          n12 = poly.createNode(n11.pos() - [0., bound + paraDepth])
          n14 = poly.createNode(n4.pos() + [bound, 0.])
          n13 = poly.createNode(n14.pos() - [0., bound + paraDepth])
  
          poly.createEdge(n1, n11, pg.core.MARKER_BOUND_HOMOGEN_NEUMANN)
          poly.createEdge(n11, n12, pg.core.MARKER_BOUND_MIXED)
          poly.createEdge(n12, n13, pg.core.MARKER_BOUND_MIXED)
          poly.createEdge(n13, n14, pg.core.MARKER_BOUND_MIXED)
          poly.createEdge(n14, n4, pg.core.MARKER_BOUND_HOMOGEN_NEUMANN)
          poly.addRegionMarker(n12.pos() + [1e-3, 1e-3], 1, boundaryMaxCellSize)
  
      poly.createEdge(n1, n2, 1)
      poly.createEdge(n2, n3, 1)
      poly.createEdge(n3, n4, 1)
      poly.addRegionMarker(n2.pos() + [1e-3, 1e-3], 2, paraMaxCellSize)
  
      # define surface
      nSurface = []
      nSurface.append(n1)
      if paraDX == 0.0:
          paraDX = 1.0
  
      if not noSensors:
          for i, e in enumerate(sensors):
              if iz == 2:
                  e.rotateX(-math.pi / 2)
              if paraDX >= 0.5:
                  nSurface.append(poly.createNode(e, pg.core.MARKER_NODE_SENSOR))
                  if i < len(sensors) - 1:
                      e1 = sensors[i + 1]
                      if iz == 2:
                          e1.rotateX(-math.pi / 2)
                      nSurface.append(poly.createNode((e + e1) * 0.5))
                  # print("Surface add ", e, el, nSurface[-2].pos(),
                  #        nSurface[-1].pos())
              elif paraDX < 0.5:
                  if i > 0:
                      e1 = sensors[i - 1]
                      if iz == 2:
                          e1.rotateX(-math.pi / 2)
                      nSurface.append(poly.createNode(e - (e - e1) * paraDX))
                  nSurface.append(poly.createNode(e, pg.core.MARKER_NODE_SENSOR))
                  if i < len(sensors) - 1:
                      e1 = sensors[i + 1]
                      if iz == 2:
                          e1.rotateX(-math.pi / 2)
                      nSurface.append(poly.createNode(e + (e1 - e) * paraDX))
                  # print("Surface add ", nSurface[-3].pos(), nSurface[-2].pos(),
                  #        nSurface[-1].pos())
      nSurface.append(n4)
  
      for i in range(len(nSurface) - 1, 0, -1):
          poly.createEdge(nSurface[i], nSurface[i - 1],
                          pg.core.MARKER_BOUND_HOMOGEN_NEUMANN)
  
      return poly
function_tokens: def createParaMeshPLC ( sensors , paraDX = 1 , paraDepth = 0 , paraBoundary = 2 , paraMaxCellSize = 0.0 , boundary = - 1 , boundaryMaxCellSize = 0 , balanceDepth = True , isClosed = False , addNodes = 1 , * * kwargs ) : if isClosed : plc = createPolygon ( sensors , isClosed = True , addNodes = addNodes , boundaryMarker = - 1 , marker = 1 , area = paraMaxCellSize , * * kwargs ) return plc noSensors = False if hasattr ( sensors , 'sensorPositions' ) : # obviously a DataContainer type sensors = sensors . sensorPositions ( ) elif isinstance ( sensors , np . ndarray ) : if sensors . ndim == 1 : sensors = [ pg . RVector3 ( s , 0 ) for s in sensors ] else : # assume 2d array with 2 or 3 values per item sensors = [ pg . RVector3 ( s ) for s in sensors ] elif isinstance ( sensors , list ) : if len ( sensors ) == 2 : # guess we have just a desired Pbox with sensors = [ pg . RVector3 ( sensors [ 0 ] , 0.0 ) , pg . RVector3 ( sensors [ 1 ] , 0.0 ) ] noSensors = True paraBoundary = 0 eSpacing = kwargs . pop ( 'eSpacing' , sensors [ 0 ] . distance ( sensors [ 1 ] ) ) iz = 1 xMin , yMin , zMin = sensors [ 0 ] [ 0 ] , sensors [ 0 ] [ 1 ] , sensors [ 0 ] [ 2 ] xMax , yMax , zMax = xMin , yMin , zMin for e in sensors : xMin = min ( xMin , e [ 0 ] ) xMax = max ( xMax , e [ 0 ] ) yMin = min ( yMin , e [ 1 ] ) yMax = max ( yMax , e [ 1 ] ) zMin = min ( zMin , e [ 2 ] ) zMax = max ( zMax , e [ 2 ] ) if abs ( yMin ) < 1e-8 and abs ( yMax ) < 1e-8 : iz = 2 paraBound = eSpacing * paraBoundary if paraDepth == 0 : paraDepth = 0.4 * ( xMax - xMin ) poly = pg . Mesh ( dim = 2 , isGeometry = True ) # define para domain without surface n1 = poly . createNode ( [ xMin - paraBound , sensors [ 0 ] [ iz ] ] ) if balanceDepth : bD = min ( sensors [ 0 ] [ iz ] - paraDepth , sensors [ 0 ] [ iz ] - paraDepth ) n2 = poly . createNode ( [ xMin - paraBound , bD ] ) n3 = poly . createNode ( [ xMax + paraBound , bD ] ) else : n2 = poly . createNode ( [ xMin - paraBound , sensors [ 0 ] [ iz ] - paraDepth ] ) n3 = poly . createNode ( [ xMax + paraBound , sensors [ - 1 ] [ iz ] - paraDepth ] ) n4 = poly . createNode ( [ xMax + paraBound , sensors [ - 1 ] [ iz ] ] ) if boundary < 0 : boundary = 4 bound = abs ( xMax - xMin ) * boundary if bound > paraBound : # define world without surface n11 = poly . createNode ( n1 . pos ( ) - [ bound , 0. ] ) n12 = poly . createNode ( n11 . pos ( ) - [ 0. , bound + paraDepth ] ) n14 = poly . createNode ( n4 . pos ( ) + [ bound , 0. ] ) n13 = poly . createNode ( n14 . pos ( ) - [ 0. , bound + paraDepth ] ) poly . createEdge ( n1 , n11 , pg . core . MARKER_BOUND_HOMOGEN_NEUMANN ) poly . createEdge ( n11 , n12 , pg . core . MARKER_BOUND_MIXED ) poly . createEdge ( n12 , n13 , pg . core . MARKER_BOUND_MIXED ) poly . createEdge ( n13 , n14 , pg . core . MARKER_BOUND_MIXED ) poly . createEdge ( n14 , n4 , pg . core . MARKER_BOUND_HOMOGEN_NEUMANN ) poly . addRegionMarker ( n12 . pos ( ) + [ 1e-3 , 1e-3 ] , 1 , boundaryMaxCellSize ) poly . createEdge ( n1 , n2 , 1 ) poly . createEdge ( n2 , n3 , 1 ) poly . createEdge ( n3 , n4 , 1 ) poly . addRegionMarker ( n2 . pos ( ) + [ 1e-3 , 1e-3 ] , 2 , paraMaxCellSize ) # define surface nSurface = [ ] nSurface . append ( n1 ) if paraDX == 0.0 : paraDX = 1.0 if not noSensors : for i , e in enumerate ( sensors ) : if iz == 2 : e . rotateX ( - math . pi / 2 ) if paraDX >= 0.5 : nSurface . append ( poly . createNode ( e , pg . core . MARKER_NODE_SENSOR ) ) if i < len ( sensors ) - 1 : e1 = sensors [ i + 1 ] if iz == 2 : e1 . rotateX ( - math . pi / 2 ) nSurface . append ( poly . createNode ( ( e + e1 ) * 0.5 ) ) # print("Surface add ", e, el, nSurface[-2].pos(), #        nSurface[-1].pos()) elif paraDX < 0.5 : if i > 0 : e1 = sensors [ i - 1 ] if iz == 2 : e1 . rotateX ( - math . pi / 2 ) nSurface . append ( poly . createNode ( e - ( e - e1 ) * paraDX ) ) nSurface . append ( poly . createNode ( e , pg . core . MARKER_NODE_SENSOR ) ) if i < len ( sensors ) - 1 : e1 = sensors [ i + 1 ] if iz == 2 : e1 . rotateX ( - math . pi / 2 ) nSurface . append ( poly . createNode ( e + ( e1 - e ) * paraDX ) ) # print("Surface add ", nSurface[-3].pos(), nSurface[-2].pos(), #        nSurface[-1].pos()) nSurface . append ( n4 ) for i in range ( len ( nSurface ) - 1 , 0 , - 1 ) : poly . createEdge ( nSurface [ i ] , nSurface [ i - 1 ] , pg . core . MARKER_BOUND_HOMOGEN_NEUMANN ) return poly