Index: /palm/trunk/SOURCE/multi_agent_system_mod.f90
===================================================================
--- /palm/trunk/SOURCE/multi_agent_system_mod.f90	(revision 3186)
+++ /palm/trunk/SOURCE/multi_agent_system_mod.f90	(revision 3187)
@@ -25,4 +25,7 @@
 ! -----------------
 ! $Id$
+! Reworked agent pathfinding to avoid collisions with walls
+! 
+! 3165 2018-07-24 13:12:42Z sward
 ! Added agent ID output
 ! 
@@ -92,4 +95,5 @@
     INTEGER(iwp) ::  number_of_agent_groups = 1  !< namelist parameter (see documentation)
     INTEGER(iwp) ::  sort_count_mas = 0          !< counter for sorting agents
+    INTEGER(iwp) ::  agt_path_size = 15          !< size of agent path array
     INTEGER(iwp) ::  step_dealloc_mas = 100      !< namelist parameter (see documentation)
     INTEGER(iwp) ::  total_number_of_agents      !< total number of agents in the whole model domain
@@ -120,5 +124,5 @@
     REAL(wp) ::  alloc_factor_mas = 20.0_wp          !< namelist parameter (see documentation)
     REAL(wp) ::  coll_t_0 = 3.                       !< namelist parameter (see documentation)
-    REAL(wp) ::  corner_gate_start = 0.7_wp          !< namelist parameter (see documentation)
+    REAL(wp) ::  corner_gate_start = 0.5_wp          !< namelist parameter (see documentation)
     REAL(wp) ::  corner_gate_width = 1.0_wp          !< namelist parameter (see documentation)    
     REAL(wp) ::  d_sigma_rep_agent                   !< inverse of sigma_rep_agent
@@ -128,14 +132,13 @@
     REAL(wp) ::  des_sp_sig = .2_wp                  !< namelist parameter (see documentation)
     REAL(wp) ::  dist_target_reached = 2.0_wp        !< distance at which target counts as reached
-    REAL(wp) ::  dist_to_int_target = .75_wp         !< namelist parameter (see documentation)
-    REAL(wp) ::  d_sqrt_2 = 1.0_wp/SQRT(2.)          !< 1/sqrt(2)
-    REAL(wp) ::  dt_agent = 0.016_wp                 !< namelist parameter (see documentation)
+    REAL(wp) ::  dist_to_int_target = .25_wp         !< namelist parameter (see documentation)
+    REAL(wp) ::  dt_agent = 0.02_wp                  !< namelist parameter (see documentation)
     REAL(wp) ::  dt_arel = 9999999.9_wp              !< namelist parameter (see documentation)
     REAL(wp) ::  end_time_arel = 9999999.9_wp        !< namelist parameter (see documentation)
     REAL(wp) ::  force_x                             !< dummy value for force on current agent in x-direction
     REAL(wp) ::  force_y                             !< dummy value for force on current agent in y-direction
-    REAL(wp) ::  max_dist_from_path = 1.0_wp         !< distance from current path at which a new path is calculated
+    REAL(wp) ::  max_dist_from_path = 0.25_wp        !< distance from current path at which a new path is calculated
     REAL(wp) ::  multi_agent_system_start = 0.0_wp   !< namelist parameter (see documentation)
-    REAL(wp) ::  radius_agent = .2_wp                !< namelist parameter (see documentation)
+    REAL(wp) ::  radius_agent = .25_wp               !< namelist parameter (see documentation)
     REAL(wp) ::  repuls_agent = 1.5_wp               !< namelist parameter (see documentation)
     REAL(wp) ::  repuls_wall = 7.0_wp                !< namelist parameter (see documentation)
@@ -143,10 +146,12 @@
     REAL(wp) ::  scan_radius_wall = 2.0_wp           !< namelist parameter (see documentation)
     REAL(wp) ::  sigma_rep_agent = 0.3_wp            !< namelist parameter (see documentation)
-    REAL(wp) ::  sigma_rep_wall = 0.2_wp             !< namelist parameter (see documentation)
+    REAL(wp) ::  sigma_rep_wall = 0.1_wp             !< namelist parameter (see documentation)
     REAL(wp) ::  tau_accel_agent = 0.5_wp            !< namelist parameter (see documentation)
     REAL(wp) ::  time_arel = 0.0_wp                  !< time for agent release
     REAL(wp) ::  time_write_agent_data = 0.0_wp      !< write agent data at current time on file
     REAL(wp) ::  v_max_agent = 1.3_wp                !< namelist parameter (see documentation)
-    
+
+    REAL(wp), DIMENSION(:), ALLOCATABLE ::  dummy_path_x  !<  dummy path (x-coordinate)
+    REAL(wp), DIMENSION(:), ALLOCATABLE ::  dummy_path_y  !<  dummy path (y-coordinate)
 
     REAL(wp), DIMENSION(max_number_of_agent_groups) ::  adx = 9999999.9_wp  !< namelist parameter (see documentation)
@@ -161,33 +166,33 @@
 !-- Type for the definition of an agent
     TYPE agent_type
-        INTEGER(iwp) ::  block_nr            !< number for sorting
-        INTEGER(iwp) ::  group               !< number of agent group
-        INTEGER(idp) ::  id                  !< particle ID (64 bit integer)
-        INTEGER(iwp) ::  path_counter        !< current target along path (path_x/y)
-        LOGICAL      ::  agent_mask          !< if this parameter is set to false the agent will be deleted
-        REAL(wp)     ::  age                 !< age of agent
-        REAL(wp)     ::  age_m               !< age of agent
-        REAL(wp)     ::  dt_sum              !< sum of agents subtimesteps
-        REAL(wp)     ::  clo                 !< clothing index
-        REAL(wp)     ::  energy_storage      !< energy stored by agent
-        REAL(wp)     ::  force_x             !< force term x-direction
-        REAL(wp)     ::  force_y             !< force term y-direction
-        REAL(wp)     ::  origin_x            !< origin x-position of agent
-        REAL(wp)     ::  origin_y            !< origin y-position of agent
-        REAL(wp)     ::  pm10                !< PM10 concentration at agent position
-        REAL(wp)     ::  pm25                !< PM25 concentration at agent position
-        REAL(wp)     ::  speed_abs           !< absolute value of agent speed
-        REAL(wp)     ::  speed_e_x           !< normalized speed of agent in x
-        REAL(wp)     ::  speed_e_y           !< normalized speed of agent in y
-        REAL(wp)     ::  speed_des           !< agent's desired speed
-        REAL(wp)     ::  speed_x             !< speed of agent in x
-        REAL(wp)     ::  speed_y             !< speed of agent in y
-        REAL(wp)     ::  thermal_index       !< the dynamic thermal index
-        REAL(wp)     ::  windspeed           !< absolute value of windspeed at agent position
-        REAL(wp)     ::  x                   !< x-position
-        REAL(wp)     ::  y                   !< y-position
-        REAL(wp)     ::  t                   !< temperature
-        REAL(wp)     ::  t_x                 !< x-position
-        REAL(wp)     ::  t_y                 !< y-position
+        INTEGER(iwp) ::  block_nr        !< number for sorting
+        INTEGER(iwp) ::  group           !< number of agent group
+        INTEGER(idp) ::  id              !< particle ID (64 bit integer)
+        INTEGER(iwp) ::  path_counter    !< current target along path (path_x/y)
+        LOGICAL      ::  agent_mask      !< if this parameter is set to false the agent will be deleted
+        REAL(wp)     ::  age             !< age of agent
+        REAL(wp)     ::  age_m           !< age of agent
+        REAL(wp)     ::  dt_sum          !< sum of agents subtimesteps
+        REAL(wp)     ::  clo             !< clothing index
+        REAL(wp)     ::  energy_storage  !< energy stored by agent
+        REAL(wp)     ::  force_x         !< force term x-direction
+        REAL(wp)     ::  force_y         !< force term y-direction
+        REAL(wp)     ::  origin_x        !< origin x-position of agent
+        REAL(wp)     ::  origin_y        !< origin y-position of agent
+        REAL(wp)     ::  pm10            !< PM10 concentration at agent position
+        REAL(wp)     ::  pm25            !< PM25 concentration at agent position
+        REAL(wp)     ::  speed_abs       !< absolute value of agent speed
+        REAL(wp)     ::  speed_e_x       !< normalized speed of agent in x
+        REAL(wp)     ::  speed_e_y       !< normalized speed of agent in y
+        REAL(wp)     ::  speed_des       !< agent's desired speed
+        REAL(wp)     ::  speed_x         !< speed of agent in x
+        REAL(wp)     ::  speed_y         !< speed of agent in y
+        REAL(wp)     ::  thermal_index   !< the dynamic thermal index
+        REAL(wp)     ::  windspeed       !< absolute value of windspeed at agent position
+        REAL(wp)     ::  x               !< x-position
+        REAL(wp)     ::  y               !< y-position
+        REAL(wp)     ::  t               !< temperature
+        REAL(wp)     ::  t_x             !< x-position
+        REAL(wp)     ::  t_y             !< y-position
         REAL(wp), DIMENSION(0:15) ::  path_x !< agent path to target (x)
         REAL(wp), DIMENSION(0:15) ::  path_y !< agent path to target (y)
@@ -514,4 +519,5 @@
        INTEGER(iwp) ::  n  !< loop variable over all agents in a grid box
        INTEGER(iwp) ::  pc !< agent path counter
+       INTEGER(iwp) ::  nobo !< agent path counter
 
        REAL(wp) ::  abs_dir         !< length of direction vector (for normalization)
@@ -535,7 +541,4 @@
 !--       If no path was calculated for agent yet, do it
           IF ( pc >= 999 ) THEN
-
-             agents(n)%path_x(0) = agents(n)%origin_x
-             agents(n)%path_y(0) = agents(n)%origin_y
              CALL mas_nav_find_path(n)
              pc = agents(n)%path_counter
@@ -577,6 +580,4 @@
 !--          of her deviation from her current path
              IF ( path_flag ) THEN
-                agents(n)%path_x(0) = agents(n)%path_x(pc-1)
-                agents(n)%path_y(0) = agents(n)%path_y(pc-1)
                 CALL mas_nav_find_path(n)
                 pc = agents(n)%path_counter
@@ -1006,4 +1007,7 @@
           DO jl = nysg, nyng
 !
+!--          Exclude cyclic topography boundary
+             IF ( il < 0 .OR. il > nx .OR. jl < 0 .OR. jl > ny ) CYCLE
+!
 !--          North edge
              IF ( jl < nyng ) THEN
@@ -3065,6 +3069,10 @@
 !--       Allocate agent arrays and set attributes of the initial set of
 !--       agents, which can be also periodically released at later times.
-          ALLOCATE( agt_count  (nysg:nyng,nxlg:nxrg),                            &
+          ALLOCATE( agt_count  (nysg:nyng,nxlg:nxrg),                          &
                     grid_agents(nysg:nyng,nxlg:nxrg) )
+!
+!--       Allocate dummy arrays for pathfinding
+          ALLOCATE( dummy_path_x(0:agt_path_size),                 &
+                    dummy_path_y(0:agt_path_size) )
 
           number_of_agents = 0
@@ -3084,5 +3092,5 @@
           zero_agent%group         = 0
           zero_agent%id            = 0_idp
-          zero_agent%path_counter  = SIZE(zero_agent%path_x)
+          zero_agent%path_counter  = agt_path_size
           zero_agent%age           = 0.0_wp
           zero_agent%age_m         = 0.0_wp
@@ -3126,4 +3134,162 @@
     END SUBROUTINE mas_init
 
+!------------------------------------------------------------------------------!
+! Description:
+! ------------
+!> Finds the shortest path from a start position to a target position using the
+!> A*-algorithm
+!------------------------------------------------------------------------------!
+    SUBROUTINE mas_nav_a_star( start_x, start_y, target_x, target_y, nsteps )
+
+       IMPLICIT NONE
+
+       LOGICAL ::  target_reached !< flag
+
+       INTEGER(iwp) ::  cur_node     !< current node of binary heap
+       INTEGER(iwp) ::  i_ag         !< agent index
+       INTEGER(iwp) ::  il           !< counter (x)
+       INTEGER(iwp) ::  jl           !< counter (y)
+       INTEGER(iwp) ::  neigh_node   !< neighbor node
+       INTEGER(iwp) ::  node_counter !< binary heap node counter
+       INTEGER(iwp) ::  path_ag      !< index of agent path
+       INTEGER(iwp) ::  som          !< size of mesh
+       INTEGER(iwp) ::  rn_side      !< index of agent path
+       INTEGER(iwp) ::  steps        !< steps along the path
+       INTEGER(iwp) ::  nsteps        !< number of steps
+
+       REAL(wp) ::  start_x      !< x-coordinate agent
+       REAL(wp) ::  start_y      !< y-coordinate agent
+       REAL(wp) ::  new_cost     !< updated cost to reach node
+       REAL(wp) ::  new_priority !< priority of node to be added to queue
+       REAL(wp) ::  rand_nr      !< x-coordinate target
+       REAL(wp) ::  rn_gate      !< random number for corner gate
+       REAL(wp) ::  target_x     !< x-coordinate target
+       REAL(wp) ::  target_y     !< y-coordinate target
+!
+!--    Coordinate Type
+       TYPE coord
+          REAL(wp) ::  x   !< x-coordinate
+          REAL(wp) ::  x_s !< x-coordinate (shifted)
+          REAL(wp) ::  y   !< y-coordinate
+          REAL(wp) ::  y_s !< y-coordinate (shifted)
+       END TYPE coord
+
+       TYPE(coord), DIMENSION(:), ALLOCATABLE, TARGET ::  path     !< path array
+       TYPE(coord), DIMENSION(:), ALLOCATABLE, TARGET ::  tmp_path !< temporary path for resizing
+
+       CALL cpu_log( log_point_s(20), 'mas_nav_find_path', 'start' )
+       node_counter = 0
+
+!
+!--    Create temporary navigation mesh including agent and target positions
+       CALL mas_nav_create_tmp_mesh( start_x, start_y, target_x, target_y, som )
+       tmp_mesh(som)%cost_so_far = 0.0_wp
+!
+!--    Initialize priority queue
+       heap_count = 0_iwp
+       ALLOCATE(queue(0:100))
+       target_reached = .FALSE.
+!
+!--    Add starting point (agent position) to frontier (the frontier consists
+!--    of all the nodes that are to be visited. The node with the smallest
+!--    priority will be visited first. The priority consists of the distance
+!--    from the start node to this node plus a minimal guess (direct distance)
+!--    from this node to the goal). For the starting node, the priority is set
+!--    to 0, as it's the only node thus far
+       CALL mas_heap_insert_item(som,0.0_wp)
+       cur_node = som
+       DO WHILE ( heap_count > 0 )
+!
+!--       Step one: Pick lowest priority item from queue
+          node_counter = node_counter + 1
+          CALL mas_heap_extract_item(cur_node)
+!
+!--       Node 0 is the goal node
+          IF ( cur_node == 0 ) THEN
+             EXIT
+          ENDIF
+!
+!--       Loop over all of cur_node's neighbors
+          DO il = 1, tmp_mesh(cur_node)%noc
+             neigh_node = tmp_mesh(cur_node)%connected_vertices(il)
+!
+!--          Check, if the way from the start node to this neigh_node via
+!--          cur_node is shorter than the previously found shortest path to it.
+!--          If so, replace said cost and add neigh_node to the frontier.
+!--          cost_so_far is initialized as 1.d12 so that all found distances
+!--          should be smaller.
+             new_cost   = tmp_mesh(cur_node)%cost_so_far                       &
+                         + tmp_mesh(cur_node)%distance_to_vertex(il)
+             IF ( new_cost < tmp_mesh(neigh_node)%cost_so_far ) THEN
+                tmp_mesh(neigh_node)%cost_so_far = new_cost
+                tmp_mesh(neigh_node)%origin_id   = cur_node
+!
+!--             Priority in the queue is cost_so_far + heuristic to goal
+                new_priority = new_cost                                        &
+                              + heuristic(tmp_mesh(neigh_node)%x,              &
+                                tmp_mesh(neigh_node)%y, tmp_mesh(0)%x,         &
+                                tmp_mesh(0)%y)
+                CALL mas_heap_insert_item(neigh_node,new_priority)
+             ENDIF
+          ENDDO
+       ENDDO
+!
+!--    Add nodes to a path array. To do this, we must backtrack from the target
+!--    node to its origin to its origin and so on until an node is reached that
+!--    has no origin (%origin_id == -1). This is the starting node.
+       DEALLOCATE(queue)
+       cur_node = 0
+       steps = 0
+       ALLOCATE(path(1:100))
+       DO WHILE ( cur_node /= -1 )
+          steps = steps + 1
+!
+!--       Resize path array if necessary
+          IF ( steps > SIZE(path) ) THEN
+             ALLOCATE(tmp_path(1:steps-1))
+             tmp_path(1:steps-1) = path(1:steps-1)
+             DEALLOCATE(path)
+             ALLOCATE(path(1:2*(steps-1)))
+             path(1:steps-1) = tmp_path(1:steps-1)
+             DEALLOCATE(tmp_path)
+          ENDIF
+          path(steps)%x = tmp_mesh(cur_node)%x
+          path(steps)%y = tmp_mesh(cur_node)%y
+          path(steps)%x_s = tmp_mesh(cur_node)%x_s
+          path(steps)%y_s = tmp_mesh(cur_node)%y_s
+          cur_node = tmp_mesh(cur_node)%origin_id
+       ENDDO
+!
+!--    Add calculated intermittent targets to the path until either the
+!--    target or the maximum number of intermittent targets is reached.
+!--    Ignore starting point (reduce index by one), it is agent position.
+       dummy_path_x = -1
+       dummy_path_y = -1
+       path_ag = 1
+       steps = steps - 1
+       nsteps = 0
+       DO WHILE( steps > 0 .AND. path_ag <= agt_path_size )
+!
+!--       Each target point is randomly chosen along a line target along the
+!--       bisector of the building corner that starts at corner_gate_start
+!--       and has a width of corner_gate_width. This is to avoid clustering
+!--       when opposing agent groups try to reach the same corner target.
+          rn_gate = random_function(iran_agent) * corner_gate_width            &
+                                                + corner_gate_start
+          dummy_path_x(path_ag) = path(steps)%x + rn_gate                      &
+                         * (path(steps)%x_s - path(steps)%x)
+          dummy_path_y(path_ag) = path(steps)%y + rn_gate                      &
+                         * (path(steps)%y_s - path(steps)%y)
+          steps = steps - 1
+          path_ag = path_ag + 1
+          nsteps = nsteps + 1
+       ENDDO
+!
+!--    Set current intermittent target of this agent
+       DEALLOCATE(tmp_mesh, path)
+       CALL cpu_log( log_point_s(20), 'mas_nav_find_path', 'stop' )
+
+    END SUBROUTINE mas_nav_a_star
+
 !------------------------------------------------------------------------------! 
 ! Description:
@@ -3324,158 +3490,78 @@
 
     END SUBROUTINE mas_nav_create_tmp_mesh
+    
 
 !------------------------------------------------------------------------------!
 ! Description:
 ! ------------
-!> Finds the shortest path from agent position to target using A*-algorithm
-!------------------------------------------------------------------------------!
-    SUBROUTINE mas_nav_find_path( i_ag )
+!> Finds the shortest path from an agents' position to her target. As the
+!> actual pathfinding algorithm uses the obstacle corners and then shifts them
+!> outward after pathfinding, cases can uccur in which the connection between
+!> these intermittent targets then intersect with obstacles. To remedy this
+!> the pathfinding algorithm is then run on every two subsequent intermittent
+!> targets iteratively and new intermittent targets may be added to the path
+!> this way.
+!------------------------------------------------------------------------------!
+    SUBROUTINE mas_nav_find_path( nl )
 
        IMPLICIT NONE
 
-       LOGICAL ::  target_reached !< flag
-
-       INTEGER(iwp) ::  cur_node     !< current node of binary heap
-       INTEGER(iwp) ::  i_ag         !< agent index
-       INTEGER(iwp) ::  il           !< counter (x)
-       INTEGER(iwp) ::  jl           !< counter (y)
-       INTEGER(iwp) ::  neigh_node   !< neighbor node
-       INTEGER(iwp) ::  node_counter !< binary heap node counter
-       INTEGER(iwp) ::  path_ag      !< index of agent path
-       INTEGER(iwp) ::  som          !< size of mesh
-       INTEGER(iwp) ::  rn_side      !< index of agent path
-       INTEGER(iwp) ::  steps        !< steps along the path
-
-       REAL(wp) ::  a_x          !< x-coordinate agent
-       REAL(wp) ::  a_y          !< y-coordinate agent
-       REAL(wp) ::  new_cost     !< updated cost to reach node
-       REAL(wp) ::  new_priority !< priority of node to be added to queue
-       REAL(wp) ::  rand_nr      !< x-coordinate target
-       REAL(wp) ::  rn_gate      !< random number for corner gate
-       REAL(wp) ::  t_x          !< x-coordinate target
-       REAL(wp) ::  t_y          !< y-coordinate target
-!
-!--    Coordinate Type
-       TYPE coord
-          REAL(wp) ::  x   !< x-coordinate
-          REAL(wp) ::  x_s !< x-coordinate (shifted)
-          REAL(wp) ::  y   !< y-coordinate
-          REAL(wp) ::  y_s !< y-coordinate (shifted)
-       END TYPE coord
-
-       TYPE(coord), DIMENSION(:), ALLOCATABLE, TARGET ::  path     !< path array
-       TYPE(coord), DIMENSION(:), ALLOCATABLE, TARGET ::  tmp_path !< temporary path for resizing
-
-       CALL cpu_log( log_point_s(20), 'mas_nav_find_path', 'start' )
-       node_counter = 0
-       a_x = agents(i_ag)%x
-       a_y = agents(i_ag)%y
-       t_x = agents(i_ag)%t_x
-       t_y = agents(i_ag)%t_y
-
-!
-!--    Create temporary navigation mesh including agent and target positions
-       CALL mas_nav_create_tmp_mesh( a_x, a_y, t_x, t_y, som )
-       tmp_mesh(som)%cost_so_far = 0.0_wp
-!
-!--    Initialize priority queue
-       heap_count = 0_iwp
-       ALLOCATE(queue(0:100))
-       target_reached = .FALSE.
-!
-!--    Add starting point (agent position) to frontier (the frontier consists
-!--    of all the nodes that are to be visited. The node with the smallest
-!--    priority will be visited first. The priority consists of the distance
-!--    from the start node to this node plus a minimal guess (direct distance)
-!--    from this node to the goal). For the starting node, the priority is set
-!--    to 0, as it's the only node thus far
-       CALL mas_heap_insert_item(som,0.0_wp)
-       cur_node = som
-       DO WHILE ( heap_count > 0 )
-!
-!--       Step one: Pick lowest priority item from queue
-          node_counter = node_counter + 1
-          CALL mas_heap_extract_item(cur_node)
-!
-!--       Node 0 is the goal node
-          IF ( cur_node == 0 ) THEN
-             EXIT
+       INTEGER(iwp) ::  nl            !< local agent counter
+       INTEGER(iwp) ::  il            !< local counter
+       INTEGER(iwp) ::  jl            !< local counter
+       INTEGER(iwp) ::  kl            !< local counter
+       INTEGER(iwp) ::  nsteps_total  !< number of steps on path
+       INTEGER(iwp) ::  nsteps_dummy  !< number of steps on path
+       
+       REAL(wp), DIMENSION(0:30) ::  ld_path_x !< local dummy agent path to target (x)
+       REAL(wp), DIMENSION(0:30) ::  ld_path_y !< local dummy agent path to target (y)
+!
+!--    Initialize agent path arrays
+       agents(nl)%path_x    = -1
+       agents(nl)%path_y    = -1
+       agents(nl)%path_x(0) = agents(nl)%x
+       agents(nl)%path_y(0) = agents(nl)%y
+!
+!--    Calculate initial path
+       CALL mas_nav_a_star( agents(nl)%x,   agents(nl)%y,                      &
+                            agents(nl)%t_x, agents(nl)%t_y, nsteps_total )
+!
+!--    Set the rest of the agent path that was just calculated
+       agents(nl)%path_x(1:nsteps_total) = dummy_path_x(1:nsteps_total)
+       agents(nl)%path_y(1:nsteps_total) = dummy_path_y(1:nsteps_total)
+!
+!--    Iterate through found path and check more intermittent targets need
+!--    to be added. For this, run pathfinding between every two consecutive
+!--    intermittent targets.
+       DO il = 0, MIN(agt_path_size-1, nsteps_total-1)
+!
+!--       pathfinding between two consecutive intermittent targets
+          CALL mas_nav_a_star( agents(nl)%path_x(il),   agents(nl)%path_y(il), &
+                              agents(nl)%path_x(il+1), agents(nl)%path_y(il+1),&
+                              nsteps_dummy )
+          nsteps_dummy = nsteps_dummy - 1
+!
+!--       If additional intermittent targets are found, add them to the path
+          IF ( nsteps_dummy > 0 ) THEN
+             ld_path_x = -1
+             ld_path_y = -1
+             ld_path_x(il+1:il+nsteps_dummy) = dummy_path_x(1:nsteps_dummy)
+             ld_path_y(il+1:il+nsteps_dummy) = dummy_path_y(1:nsteps_dummy)
+             kl = 1
+             DO jl = il+1,nsteps_total
+               ld_path_x( il+nsteps_dummy+kl ) = agents(nl)%path_x(jl)
+               ld_path_y( il+nsteps_dummy+kl ) = agents(nl)%path_y(jl)
+               kl = kl + 1
+               IF ( kl > agt_path_size ) EXIT
+             ENDDO
+             nsteps_total = MIN(nsteps_total + nsteps_dummy, agt_path_size)
+             agents(nl)%path_x(il+1:nsteps_total) = ld_path_x(il+1:nsteps_total)
+             agents(nl)%path_y(il+1:nsteps_total) = ld_path_y(il+1:nsteps_total)
           ENDIF
-!
-!--       Loop over all of cur_node's neighbors
-          DO il = 1, tmp_mesh(cur_node)%noc
-             neigh_node = tmp_mesh(cur_node)%connected_vertices(il)
-!
-!--          Check, if the way from the start node to this neigh_node via
-!--          cur_node is shorter than the previously found shortest path to it.
-!--          If so, replace said cost and add neigh_node to the frontier.
-!--          cost_so_far is initialized as 1.d12 so that all found distances
-!--          should be smaller.
-             new_cost   = tmp_mesh(cur_node)%cost_so_far                       &
-                         + tmp_mesh(cur_node)%distance_to_vertex(il)
-             IF ( new_cost < tmp_mesh(neigh_node)%cost_so_far ) THEN
-                tmp_mesh(neigh_node)%cost_so_far = new_cost
-                tmp_mesh(neigh_node)%origin_id   = cur_node
-!
-!--             Priority in the queue is cost_so_far + heuristic to goal
-                new_priority = new_cost                                        &
-                              + heuristic(tmp_mesh(neigh_node)%x,              &
-                                tmp_mesh(neigh_node)%y, tmp_mesh(0)%x,         &
-                                tmp_mesh(0)%y)
-                CALL mas_heap_insert_item(neigh_node,new_priority)
-             ENDIF
-          ENDDO
+
        ENDDO
 !
-!--    Pathfinding is done. Add nodes to a path array, then give the
-!--    first 15 intermittent targets to the agent.
-       DEALLOCATE(queue)
-       cur_node = 0
-       steps = 0
-       ALLOCATE(path(1:100))
-       DO WHILE ( cur_node /= -1 )
-          steps = steps + 1
-!
-!--       Resize path array if necessary
-          IF ( steps > SIZE(path) ) THEN
-             ALLOCATE(tmp_path(1:steps-1))
-             tmp_path(1:steps-1) = path(1:steps-1)
-             DEALLOCATE(path)
-             ALLOCATE(path(1:2*(steps-1)))
-             path(1:steps-1) = tmp_path(1:steps-1)
-             DEALLOCATE(tmp_path)
-          ENDIF
-          path(steps)%x = tmp_mesh(cur_node)%x
-          path(steps)%y = tmp_mesh(cur_node)%y
-          path(steps)%x_s = tmp_mesh(cur_node)%x_s
-          path(steps)%y_s = tmp_mesh(cur_node)%y_s
-          cur_node = tmp_mesh(cur_node)%origin_id
-       ENDDO
-!
-!--    Add calculated intermittent targets to agent path until either the 
-!--    target or the maximum number of intermittent targets is reached.
-!--    Ignore starting point (reduce index by one), it is agent position.
-       path_ag = 1
-       steps = steps - 1
-       DO WHILE( steps > 0 .AND. path_ag < SIZE(agents(i_ag)%path_x) )
-!
-!--       Each target point is randomly chosen along a line target along the
-!--       bisector of the building corner that starts at corner_gate_start
-!--       and has a width of corner_gate_width. This is to avoid clustering
-!--       when opposing agent groups try to reach the same corner target.
-          rn_gate = random_function(iran_agent) * corner_gate_width            &
-                                                + corner_gate_start
-          agents(i_ag)%path_x(path_ag) = path(steps)%x + rn_gate               &
-                                         * (path(steps)%x_s - path(steps)%x)
-          agents(i_ag)%path_y(path_ag) = path(steps)%y + rn_gate               &
-                                         * (path(steps)%y_s - path(steps)%y)
-          steps = steps - 1
-          path_ag = path_ag + 1
-       ENDDO
-!
-!--    Set current intermittent target of this agent
-       agents(i_ag)%path_counter = 1
-       DEALLOCATE(tmp_mesh, path)
-       CALL cpu_log( log_point_s(20), 'mas_nav_find_path', 'stop' )
+!--    reset path counter to first intermittent target
+       agents(nl)%path_counter = 1
 
     END SUBROUTINE mas_nav_find_path
Index: /palm/trunk/SOURCE/netcdf_interface_mod.f90
===================================================================
--- /palm/trunk/SOURCE/netcdf_interface_mod.f90	(revision 3186)
+++ /palm/trunk/SOURCE/netcdf_interface_mod.f90	(revision 3187)
@@ -25,4 +25,7 @@
 ! -----------------
 ! $Id$
+! Changed agent output to precision NF90_DOUBLE
+! 
+! 3165 2018-07-24 13:12:42Z sward
 ! Added agent ID output
 ! 
@@ -1992,5 +1995,5 @@
              CALL netcdf_create_var( id_set_agt, (/ id_dim_agtnum,             &
                                      id_dim_time_agt /), agt_var_names(i),     &
-                                     nc_precision(8), id_var_agt(i),           &
+                                     NF90_DOUBLE, id_var_agt(i),           &
                                      TRIM( agt_var_units(i) ),                 &
                                      TRIM( agt_var_names(i) ), 339, 340, 341 )
