Agent Based Force Vector Model of Social Influence

No preview image

2 collaborators

Default-person Moody Ahmad (Author)
G. Jordan Maclay (Author)

Tags

Visible to everyone | Changeable by the author
Model was written in NetLogo 6.1.1 • Viewed 491 times • Downloaded 44 times • Run 0 times
Download the 'Agent Based Force Vector Model of Social Influence' modelDownload this modelEmbed this model

Do you have questions or comments about this model? Ask them here! (You'll first need to log in.)


## Abstract

The model is based on a vector representation of each agent. The components of thevector are the key continuous “attributes” that determine the social behavior of theagent. A simple mathematical force vector model is used to predict the effect of eachagent on all other agents. The force law used is motivated by gravitational force lawsand electrical force laws for dipoles. It assumes that the force between two agents isproportional to the ”similarity of attributes”, which is implemented mathematically asthe dot product of the vectors representing the attributes of the agents, and the forcegoes as the inverse square of the difference in attributes, which is expressed as theEuclidean distance in attribute space between the two vectors. The force between theagents may be positive (attractive), zero, or negative (repulsive) depending on whetherthe angle between the corresponding vectors is less than, equal to, or greater than 90°.A positive force causes the attributes of the agents to become more similar and thecorresponding vectors to become more nearly parallel. Interaction between all agents isallowed unless the difference between the attributes representing the agents exceeds aconfidence limit (the Attribute Influence Bound) set in the simulation. Similar agentstend to form groups. For small values of the Attribute Influence Bound, numerousgroups remains scattered throughout attribute space at the end of a simulation. As theAttribute Influence Bound is increased, and agents with increasingly different attributescan communicate, fewer groups remain at the end, and the remaining groups haveincreasingly different characteristic attributes. With a large Attribute Influence Boundall agents are connected and extreme bi- or tri-and occasional quadri-polarizationresults. During the simulations, depending on the initial conditions, collective behaviorsof grouping, consensus, fragmentation and polarization are observed as well as certainsymmetries specific to the model, for example, the average of the attributes for allagents does not change significantly during a simulation.

## WHAT IS IT?

This model is exploring how simple rules can create complex behaviors. We start with several basic rules.

* The universe is represented by a vector space, currently 2-D, in which the coordinates represent continuous measurable attributes characterizing the agents in the space. It is assumed that the behavior of the agents (ie their movement in the vector space) depends on their attributes and their interactions with other agents.

* Each agent is represented by a vector A(xa, ya) in the space. All vectors start at the origin (0,0) and end at the point (xa, ya), where -100

* Each agent A has a mass mA associated with it. The influence of an agent A on another agent is proportional to its mass mA

* There are forces, attractive and repulsive, between any two agents A(xa,ya) and B(xb,yb) that depend on the relative orientation of the vectors representing the agents. The force of A on B is proportional to the dot product of the vectors AdotB times the mass of A, divided by the square of the distance between the agents (A-B)^2=R^2, times an overall scale factor g. The force is a vector directed along the line connecting the heads of the vectors. The force is akin to a gravitational force except for presence of the dot product, which is reminiscent of the force between electrical dipoles.

* The force of agent A on agent B causes an accelertion of agent B which equals the force of A on B divided by the mass mB of agent B. The acceleration is exerted on an agent for a time interval DT, which causes a movement of the agent which equals the acceleration times (DT)2 . In each iteration, all movements are calculated for each agent and the agents are moved accordingly.

> FAonB = g mA ( (A . B) / R2) (A-B)/R

We assume

FAonB = mB aB

solving for the acceleration aB on B due to force of A, we get

aB = g (mA / mB) ( (A . B) / R2) (A-B)/R

where A, B, and F are vectors and R is the magnitude of the vector A-B

R = sqrt ((xa - xb) 2 + (ya - yb) 2)

g is the gravitational constant and a is the acceleration.

The force between two agents is attractive if their vectors tend to point in the same direction, which means the absolute value of the angle between the vectors representing the agents is 90 degrees or less

(or the algebraic difference in the angles is between -90 and +90).

The force between two agents is repulsive if their vectors tend to point in opposite directions, which means the absolute value of the angle between the vectors representing the agents is greater than 90 degrees

(or the algebraic difference in the angles is greater than 90 and less than 270).

Attribute Influence Bound (AIB)

If the distance R between two agents exceeds the value set in the Attribute Influence Bound (AIB) slider then we assume the agents do not communicate and the force between the agents is automatically set to zero. The maximum value of the AIB is about 280, which is the distance from one corner of the 200x200 space to the opposite corner.

Setting the time interval DT

If AdaptiveDT is NOT selected:

Then the value on the DT slider is used. In each iteration of the simulation, the movement of each agent is computed.

If AdaptiveDT IS selected:

If the forces are very small, then DT is increased until the largest movement of an agent is set equal to the Coalescence Radius. On the other hand if the forces are very large, then DT is reduced so that the maximum distance traveled in one iteration for any agent is equal to the Coalescence Radius CR. Use of AdaptiveDT provides an efficient way to simulate situations in which forces are small and yet may act for long times.

Movement of Agents

The force of A on B causes an acceleration aB of the vector B that goes inversely with mB, the inertial mass of B resisting the change in the vector B. The acceleration acts for a time step DT causing a displacement of the vector B equal to DeltaB. The displacements of all agents due to the force on each other are computed in each time step.

> DeltaB = (FAonB / mB)(DT)2

DeltaB = g (mA /mB) (DT)2 ((A . B)/ R2)(A - B)/R

This particular model demonstrates attraction and repulsion in a vector space. If the distance R between two agents becomes less than a preset value, the Coalescence Radius CR, the agents are merged into a group, with a mass equal to the sum of the masses of the component agents. The force laws for groups are the same as for individual agents. Once an agent is part of a group, the agent cannot leave the group.

The universe is infinite. Agents can move beyond the boundaries of the 200 x 200 universe. Their departure point from the visible universe is indicated by a ghost agent. The agents continue to operate in the invisible, infinite universe according to the same rules as in the visible universe. Agents in the invisible universe continuously manifest themselves at their point of departure from the visible universe. The center of the universe is indicated by a bullseye at coordinates (0,0).

## HOW TO USE IT

### Controls

#### Setup

* Before setup, select / setup the following parameters:

* **Number** of agents- 0-200

* **Spatial** distribution of agents: Random, Normal, or Exponential. The spatial distribution for each coordinate (x,y) is set independently. This is also true for the mean and standard deviations for each coordinates distribution. These are set by **xMean**, **xStd** and **yMean**, **yStd**

* **Random** Distribution - mmean and stddev are ignored for random distribution

* **Normal** Distribution - mmean gives the location (mmean,mmean) of the center of the distribution. The standard deviation ranges from 0 to 1. A standard deviation of 1 means a distance of 100 in our coordinate system. NOTE: In random or normal distributions, if the random number generator places a particular agent outside the boundaries 200 x 200, then a new random number is chosen for the next agent, and the process is continued until the number of initial agents requested are all placed within the boundaries. This process occurs regularly for a normal distribution with a standard deviation above about 0.5.

* **Exponential** Distribution - is equivalent to ( - mean ) * ln random-float 1.0. This is scaled to the size of the universe 200 x 200.

* **Mass** distribution of the agents that are created. Maxmass - this is the maximum mass that is allowed for any of the mass distributions. The SD standard deviation in mass also needs to be specified for the normal distribution. The force of agent A on agent B is proportional to the mass of agent A. The movement of agent B from the force due to A goes inversely as the mass of agent B.

* **Random** - all agent masses are between 1 and maxmass

* **Normal** - all masses are normally distributed around mass-mean with mass-stddev and between 1 and maxmass.

* **Exponential** - is equivalent to ( - mass-mean ) * ln random-float 1.0. The mass is always between 1 and maxmass

* **Attribute Influence Bound (AIB)** - This is the maximum distance between two agents at which they affect each other. There is no interaction between agents that are farther apart than the AIB. The largest possible distance in the 200 x 200 universe is the hypoteneuse 200 SqRt(2) = 283.

* **Distance exponent** - this is exponent for the distance (R - normally set to 2) in the force equation: FAonB = g mA ( (A . B) / RDistanceExponent) (A-B)/R

* **Coalescence Radius (CR)** - If two agents move closer together than the coalescence radius, then the agents are merged into one group agent and the mass of the group is the sum of the masses of the component agents. CR is typically set to 0.3. The location of an individual agent is shown by a circle. After two individual agents coalesce, the resulting group is represented as a triangle. The numbers beside the symbols indicate the corresponding mass.

* **g** - This is the overall constant that scales the force between two agents, similar to the gravitational constant for gravitational forces. Typically set to 7 x 10^-5 .

* **AdaptiveDT** - time granularity is important for running the simulation in reasonable time frames. The default value for the time step is DT=1. If AdaptiveDT set to "on" , the simulation runs and the value of DT is varied to insure that the maximum movement of an agents equals the Coalescence Radius. The current value of DT is displayed in the slider for each iteration and plotted in the DT plot. We have noticed more than an order of magnitude reduction in elapsed time to reach a final state with AdaptiveDT. We have compared the end results and verified that the end results are equivalent with a AdaptiveDT and a low value of DT for smooth dynamics.

With AdaptiveDT off, you can set the value of DT that you want to use for the simulation with the slider. The value is fixed for all iterations. The default is 1.

* **Randomseed** - if set to 0, each simulation run will generate a different random placements of agents and their masses. If Randomseed is set to a nonzero integer, that seed will allow you to start the simulation with the exactly the same random initial conditions of agent placements and masses and colors. This is useful for repeating scenarios where you want to test the same initial condition while varying some of the other parameters, e.g., Coalescence Radius.

* **ProbDist** - is the probability distribution chosen for agent interactions.

* None - all agents interact / influence each other depending on other parameters such as AIB.

* AttributeDiff - agent interaction probability is based on the difference in attributes between agents. If the agent attributes are orthogonal to each other, then the probability of their interaction is zero. If the attributes are in total alignment, the probability of interaction is 100 %.

* DistanceProb - the probability is (AIB - Dist) / AIB where Dist is the distance between the agents.

* **infprob** - influence probability is the percentage of agents that are influenced by others. For example, if it is set to 10, 10% of the agents will be influenced by others. Which agents are not influenced is random.

* **track** - agents / groups leave a track of their trajectory as they move.

#### Simulation Stopping Conditions

There are four conditions that cause the simulation to stop:

* No movement - force is zero for all agents. AIB exceeded or probability factors.

* ItStop - number of iterations requested reached

* AgentCount - stop at given number of agents left.

* DTStop - Stop if dt >= the given nonzer value.

#### Monitors

On the bottom of display:

* **totmass** - at bottom of display, this monitor give the total mass of all agents in the simulation

* **agents** - shows the total number of agents active at any given time in the simulation which equals individual agents plus group agents

* **elapsed-time** shows the sum of the DT values used in the simulation to this point.. One additional DT value is added to elapsed time for each iteration .

* **iterations** - total number of iterations (time steps) that the model has run at any point in the simulation. **Note:** With dynamic dt, ticks (on the top) actually shows elapsed time. Iterations shows the actual number of iterations of the simulation.

* **stopreason** - why simulation stopped

* **Final DT** - final value of dt at end of simulation

* **Oob #** out of bounds count - how many agents fall outside the universe during initial setup. The out of bounders are deleted and not used in the simulation.

On right side of display

* peakdist - this give the maximum distance an agent would travel in the current iteration assuming DT = 1. If AdaptiveDT is on, then DT will be modified so the actual maximum distance the agent travels is the coalescence distance CR.

* repulsive - this is the sum of the repulsive forces for the current iteration

* attractive - this is the sum of the attractive forces for the current iteration

#### Optional Controls

On the LEFT side of the display

* **tickstop** - if nonzero, stop after that many iterations.

* **AgentStop** - if non-zero, simulation stops when the agent count is less than or equal to this number.

* **DTStop** - if nonzero, stop if dt is >= to this value.

* **forceAdj** - changes the application of the force law.

* **Normal** - both positive and negative forces are in play. If A . B is positive, the force is attractive, If A . B is negative, the force is repulsive.

* **AttractOnly** - all forces are attractive only. If A . B is negative it's absolute value is used

* **RepulseOnly** - all force calculation are turned negative, minus the absolute value of F is used.

* **NoAttract** - all attractive forces are set to zero so that only repulsive forces are in play.

* **NoRepulse** - all repulsive forces are set to zero so that only attractive forces are in play.

* **Invert** - forces are inverted. If attractive, they are made repulsive and vice versa.

* **Create** Agent - allows manual creation of an agent by using the mouse to place agents on the display grid. Multiple agents may be created, one at a time.

* **Initial**-mass sets the mass of the created agent and

* **Agent**-color sets the color of the created agent (a number between 0 and 140).

* **debug** - shows debug messages at various simulation points.

* **center** - calculates the center of mass of all the agents and moves them so that the center of mass is at the origin.

* **World** - Clicking this button at any time will create a "world.csv" file that captures all the data on the interface, i.e., all the plots, values of global variables, all the positions and attributes of all the agents, and all the attibutes of each cell of the universe.

* **OutputData** - Clicking this button exports all the plots on the interface as a csv file called "counter.csv"

* **rotateAxes**-slider to set value to 0 to 360 degrees

* **ROTATE** button, this causes the system to rotate the coordinate system clockwise the number of degrees specified in the rotateAxes slider.

* **Record view** - if clicked before go, it will make a movie of the simulation with one frame for each iteration.

* **Record intfc** - if clicked before go, it will make a movie of the interface with one frame for each iteratin.

On the RIGHT side of the display

* Number injected- this allows the injection of a specified number of agents, placed according the initial condition selected (random, normal distribution or exponential).

* InjectionMaxMass- this specifies the mass of the injected agents. All injected agents have this same mass.

* ShowForces - shows the force vectors for each actor / group at each iteration step. **Note** that the size of sthe force vector is relative at each iteration. At each iteration, the maximum force is calculated. that force is scaled (by 40 units) to be the maximum force vector length. All other force vectors use that as the measure for that iteration.

* xOirigin - shifs the x origin left ( -# ) or right ( +# ). This is done at setup time before any iteration is done. **Note** that this is the same as shifting a normal distribution left or right by the specified amount.

* yOirigin - shifs the y origin down ( -# ) or up ( +# ). This is done at setup time before any iteration is done.

##### Fixed Geometries of Agents

This allows the creation of initial conditions in which agents have regular polygonal geometries. It allsws the creation of grids of nested polygins. **Note** that the masses of the agents created are determined by the mass distribution selections for active and passive masses.

* Geometry: on/off. Off is normal operation. No injections. On injects polygons.

* Nsides - slider from 1 to 100. Indicates the number of sides for a regular polygon

* Pradius - slider that indicates the distance to a vertex from the origin

* Prange - slider to indicate the range of the polygons, maximum x value for a vertex.The calculations assume that the first vertex is on the x axis with y = 0

* Pstep - slider to indicate the radius growth till the range limit is met

* Pxcenter - is the center of the polygon. Initially set to 0. However, you can move the center of the polygons anywhere in the universe. Caveat,

* Pycenter - is the y coordinate for the center of polygons.

Filling capability allows the creation of agents along the sides of the polygon created.

* fill - on / off. Off is normal operation, Only agents at the vertices of polygons

* filldistance - is the distance between a vertex and an agent on the side of a polygon. Agents are created filldistance apart till the next vertex is reached. No agents beyond the polygon sides or vertices are created.

##### Hidden Features

With randomseed set to 0, Netlogo generates its own seed. If one sees behavior on such a run that one would like to reproduce, one can get the seed used for that run by typing in the observer text / command box: _**rseedused**_. That seed can be put into the randomseed text box to rerun that simulation.

### Plots

**Agent Counter**

* **turtles** - the total count of all the active agents for each iteration which equals the sum of individual agents and group agents

* **groups** - the total number of all agent groups resulting from coalescence of individual agents for each iteration

**mean distances**

* **meandist**- mean distance between all the agents for each iteration, irrespective of whether a particular agent is within the ID

* **meanxsd** - standard deviation of the mean x distance between agents for each iteration

* **meanysd** - standard deviation of the mean y distance between agents for each iteration

* **meandistclosestneighbor** - the mean distance to the closesest neighbor for all agents for each iteration irrespective of the ID

* **dcnsd** - standard deviation of distance to closest neighbor for each iteration (if the screen display is made smaller, sometimes the legend for this does not display fully)

**maxdist meanxy**

* **meanxloc** - active mass weighted mean x coordinate for all agents for each iteration. This equals Σ [active mass of agenti times its x coordinate xi]/total active mass of all agents. This is the center of mass of the system. To be able to visualize its change easily, we added a center of mass agent to the current location of the center of active mass at each iteration of the model. This movement is traced and you can see how the center of active mass changes during the simulation. The trajectory of the changing center of mass is indicated by changes in its color. It start red and progresses to higher colors.

* **meanyloc** - mass weighted mean y coordinate for all agents for each iteration calculated same way as meanxloc

* **maxdist** - the maximum distance that is traveled by an agent for each iteration. If DynamicDT is on, then maxdist will equal the Coalescence Radius.

**Median R**

* **median** of the distances of the agents from the origin

* **mean** of the distances of the agents from the origin

* **standard** deviation of the median of the distances

**DeltaT**

* plot of the value of DT versus the iteration number. DT would be constant equal to 1 or the set value of DT if AdaptiveDT is off. If AdaptiveDT is on, the plot gives the values of DT employed in the simulation to secure maximum agent movements equal to the Coalescence Radius.

**Elapsed Time**

*Plot of the elapsed time (which is the sum of the values of DT) on the y-axis versus the iteration number on the x-axis.

**mass distribution**

* **histogram** of the mass distribution of the active agents (both individual and group agents)

**Forces**

* Attract- shows the total of the attractive forces on all agents for each iteration

* Repulse - the total of the repulsive forces for each iteration

* Net force - the difference between attractive and repulsive forces for each iteration

* mmass - the amount of mass that has merged on an iteration. Note the forces at merge time.

* mcount - number of merges in an iteration

**peakdist**

* peakdist - this is the maximum distance that an agent would move in an interation assuming that DT=1. (Note: If DynamicDT is on, then the actual value of DT used is modified to limit the actual maximum distance to CR, the coalescence radius. peakdist is computed to determine the value of DT required for this.)

**dcn** (distance to closest neighbor)

* histogram of the distance to closest neightbor DCN, scale is from 0 to about 300.

**Angles**

* Histogram of the number of agents as a function of the angle at which the agents are located. The angle 0-360 degrees is measured clockwise from the vertical axis.

**Annular**

* Histogram of the number of agents as a function of their distance 0 to 140 from the center (0,0).

**Moment of Inertia**

* Plot of the sum of the each mass * R2 at each simulation step. This number is downscaled by dividing by 106 for plotting purposes.

**Force Ratio**

* ratio - 100 * repulsive force / ( attractive + repulsive ). Note the 100 multiplier is for being able to visualize the graph values better.

* repulsive - repulsive force at each step

## Copyright and License

Creative Commons Attribution-NonCommercial-ShareAlike 4.0 International Public License.

License details at https://creativecommons.org/licenses/by-nc-sa/4.0/legalcode

Note: For full disclosure: This model base was the N-Bodies model in the Netlogo Sample Models library under Chemistry and Physics -> Mechanics -> unverified -> N-Bodies. That

was a starting point. The model has been modified almost completely from the starting point.

Comments and Questions

Please start the discussion about this model! (You'll first need to log in.)

Click to Run Model

breed [actors actor]
breed [cogs cog]
breed [forces force]
breed [deltats deltat]
breed [cus cu]
directed-link-breed [ldts ldt]
directed-link-breed [fvecs fvec]

forces-own [
  mag    ;; size of vector
]

actors-own [
  fx     ;; x-component of force vector
  fy     ;; y-component of force vector
  xc     ;; real x-coordinate (in case agent leaves world). these are used for all calculations and then used to update xcor, ycor.
  yc     ;; real y-coordinate (in case agent leaves world)
  mass   ;; the actor's active mass
  massP  ;; passive mass
  dxc     ;; delta x coord change
  dyc     ;; delta y coord change
  dcn     ;; distance to closest neighbor calculate for each iteration.
  mag     ;; size of vector. Calculated for each iteration.
  angle   ;; angle of vector. Calculated for each iteration.
]

globals
[ center-of-mass-yc ;; y-coordinate of the center of mass. Used to recenter all agents around the center of mass of the whole population.
  center-of-mass-xc ;; x-coordinate of the center of mass
  maxforce          ;; max force on each iteration. Used to determine when to stop the simulation - when maxforce < min force cutoff
  maxdist           ;; max distance traveled in an iteration
  peakdist          ;; peak dist for an iteration. When dynamic dt is on: the max dist traveled is =< than the coalescence radius.
  meandist          ;; mean distance between all agents
  repulsive         ;; total repulsive force across all agents for each iteration
  attractive        ;; total attractive force
  agentcount        ;; count of actors
  meanxloc          ;; mass weighted x location for all agents
  meanyloc
  meanxsd           ;; mass weighted x location standard deviation for all agents
  meanysd
  meandistclosestneighbor   ;; mean distance to closest neighbor
  dcnsd             ;; standard deviation of distance to closest neighbor
  meandistorigin    ;; eman distance to the origin
  scale             ;; scale multiplier factor from a -1,1 world.
  masscale          ;; sise of agent scaled by mass (.1 for scale 1)
  totmass           ;; total mass of agents used for debugging only
  elapsed-time      ;; time elapsed is sum of dts
  iterations        ;; number of simulation iterations
  stopflag          ;; when set, stop simulation
  stopreason        ;; why the simulation was stopped
  mergeCount        ;; number of mergers in an iteration
  mergeTotMass      ;; merge mass for each iteration
  groups             ;; number of groups
  finaldt           ;; final dt at end of simulation
  record-view       ;; make movie of view
  record-interface  ;; make movie of interface
  forcescale        ;; how much to scale force vector size
  mominertia        ;; moment of inertia
  timestart         ;; start and end times for a run
  timeend
  oobcount          ;; count of agents that fall outside universe during setup
  rseedused         ;; random seed used for the run
  itcounter         ;; used to iterate past probability based endpoint to make sure everything is in a final stop condition
]


; Basic Model Design:
;   Setup initializes the model for a simulation run.
;     The spatial and mass distributions selected for the agents are set up
;     All necessary globals are initialized
;     Note: randomseed is initialized for repeatable runs


;;;;;;;;;;;;;;;;;;;;;;;;
;;; Setup Procedures ;;;
;;;;;;;;;;;;;;;;;;;;;;;;

to setup
  clear-all
;;  set timestart read-from-string remove "\n" (shell:exec "date" "+%s")
  set itcounter 0
  set oobcount 0
  set forcescale 40
  set scale 100
  set stopflag false
  set masscale .03
  set peakdist 0
  set dt 1
  set elapsed-time 0
  set iterations 0
  set-default-shape actors "circle"
  set record-view False
  set record-interface False
  ifelse randomseed != 0 [
    random-seed randomseed
    set rseedused randomseed
  ] [
   set rseedused new-seed
   random-seed rseedused
  ]
  create-actors number [
    ;;set color (  random 5  ) + (( random  14 ) * 10)
    set color (  random 9  ) + (( random  14 ) * 10)
    ;set color random 140
  ]
  ask patches [
    set pcolor white
  ]
  random-initial-setup
  if Geometry [
    doGeometry
  ]

  mass-setup
  set totmass 0
  ask actors [
    set totmass totmass + mass
  ]
  if NumberInjected > 0 [
    create-actors NumberInjected [
      set xc random-float (2 * scale) - scale
      set yc random-float (2 * scale) - scale
      setxy xc yc
      set mass InjectionMaxMass
      set massP InjectionMaxMass
      set size masstosize mass
    ]
  ]

  meanlocs
  ; center of gravity display
  create-cogs 1 [
    set xcor meanxloc
    set ycor meanyloc
    set color 15
    set pen-size 3
    pen-down
  ]
  ;; create identifier agent for center of universe
  create-cus 1 [
    set xcor 0
    set ycor 0
    set color yellow
    set shape "target"
    set size 5
  ]
  if xOrigin != 0 or yOrigin != 0 [
    ask actors [
      pen-up
      ifelse (xcor + xOrigin) > max-pxcor [
        set xcor max-pxcor - 1
      ][
        set xcor xcor + xOrigin
      ]
      ifelse (ycor + yOrigin) > max-pycor [
        set ycor max-pycor - 1
      ][
        set ycor ycor + yOrigin
      ]
      pen-down
    ]
  ]
  reset-ticks
end 

to random-initial-setup
  ask actors [
    if xSpatialDist = "Random" [
       set xcor random-float (2 * scale) - scale
    ]
    if ySpatialDist = "Random" [
       set ycor random-float (2 * scale) - scale
    ]
    if xSpatialDist = "Normal" [
       set xcor random-normal-in-bounds xMean (scale * xStd) (- scale) scale
    ]
    if ySpatialDist = "Normal" [
       set ycor random-normal-in-bounds yMean (scale * yStd) (- scale) scale
    ]
    if xSpatialDist = "Exponential" [
       set xcor random-exponential-pos-in-bounds xMean (- scale) scale
    ]
    if ySpatialDist = "Exponential" [
       set ycor random-exponential-pos-in-bounds yMean (- scale) scale
    ]
    set xc xcor
    set yc ycor
    if ShowForces [
      hatch-forces 1 [
        create-fvec-from myself [
          set thickness 1
          set color red
        ]
        hide-turtle
      ]
    ]
    if track [
      pen-down
    ]
  ]
end 

to mass-setup
  let locmass 0
  let locmassp 0
  ask actors [
    if active-mass-distribution = "Random"
      [ set locmass ( random-float maxmass ) ]
    if active-mass-distribution = "Normal"
      [ set locmass random-normal-in-bounds mass-mean mass-stddev 1 maxmass ]
    if active-mass-distribution = "Exponential"
      [ set locmass random-exponential-in-bounds mass-mean 1 maxmass ]
    if passive-mass-distribution = "Random"
      [ set locmassp ( random-float maxmass ) ]
    if passive-mass-distribution = "Normal"
      [ set locmassp random-normal-in-bounds pmass-mean pmass-stddev 1 maxmass ]
    if passive-mass-distribution = "Exponential"
      [ set locmassp random-exponential-in-bounds pmass-mean 1 maxmass ]
    ifelse PassiveMass [
      set mass locmass
      set massP locmassp
    ][
      set mass locmass
      set massP locmass
    ]
    set size masstosize mass
  ]
end 

to create-agent
  if mouse-down?
  [ let mx mouse-xcor
    let my mouse-ycor
    let mz 0
    if (not any? actors-on patch mx my )
    [
      create-actors 1
      [ set xc mx ;initial-position-x
        set yc my ;initial-position-y
        setxy xc yc
        set mass initial-mass
        set massp initial-mass
        set size masstosize mass
        set color agent-color
        if track [
          pen-down
        ]
      ]
      display
    ]
  ]
  while [mouse-down?]
  []
end 

;;;;;;;;;;;;;;;;;;;;;;;;;;
;;; Runtime Procedures ;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;

; Runtime Design
;  There are several controls that determine what happens at runtime:
;    tickstop - set to a nonzero value, will stop the simulation when the number of iterations selected is reached
;    record-view or record-interface - start a movie creation for the run
;    AIB and MaxDT settings can both stop a simulation if those  values are reached. If this happens, a stopflag and
;      stopreason is set to indicate the end of the simulation. The go function checks this flag at the end of each iteration
;      and stops the simulation.
;
;  NOTE: the coordinates used for the simulation are defined agent variables xc, xy. The netlogo agent coordinates
;        are used to set xc, xy at the beginning of each iteration. Then xc, xy are used for all the movement calculations.
;        Agent xcor, ycor are set by function adjust-position after all the force and movement calculations are done.
;        This is done near the end of each iteration before plots are updated.
;  NOTE; for clarity of design and modularity, the ask actors functions is invoked for collision / merger checks,
;        force calculations, max movement calculations (for stopping conditions and dynamic dt setting),
;

to go
  if tickstop != 0 [
    if iterations > tickstop [
      set stopreason "ItStop"
;;      set timeend read-from-string remove "\n" (shell:exec "date" "+%s")
;;      movie
      stop
    ]
  ]
  if AgentStop != 0 [
    if AgentStop >= count actors [
      set stopreason "AgentCount"
      stop
    ]
  ]

;  if record-view or record-interface [
;    if vid:recorder-status = "inactive" [
;      vid:start-recorder
;    ]
;    movie-init
;  ]

  set attractive 0
  set repulsive 0
  set stopflag false
  set mergeCount 0
  set mergeTotMass 0
  ask actors
  [ set fx 0
    set fy 0
;    if xc != xcor [
;      user-message (word "xcor xc mismatch: " xcor " " xc)
;    ]
;    if yc != ycor [
;      user-message (word "ycor yc mismatch: " ycor " " yc)
;    ]
    set label int mass
    set label-color black
  ]
  set maxforce 0
  set maxdist 0
  set peakdist 0
  ;; must do all of these steps separately to get correct results
  ;; since all actors interact with one another

  ask actors [ check-for-collisions
    set label int mass ]
  meanlocation
  ask actors [ update-force ]
  ask actors [ peakdist-calc ]
  if ShowForces [
    show-force
  ]

  if peakdist = 0 [
    ifelse Infprob != 100 or ProbDist != "None" [
      set itcounter itcounter + 1
      if itcounter > 5000 [
        set stopflag true
        set stopreason "No movement"
        update-plots
      ]
      set peakdist 1
    ] [
        set stopflag true
        set stopreason "No movement"
        update-plots
    ]
  ]
  if stopflag [
;    set timeend read-from-string remove "\n" (shell:exec "date" "+%s")
;    movie
    stop
  ]
  if AdaptiveDT [
    set dt sqrt ( CoalescenseRadius / peakdist )
  ]
  ifelse DTStop != 0 and dt >= DTStop [
    set stopflag true
    set finaldt dt
    set stopreason "DTStop"
    update-plots
  ] [
    ask actors [ update-position ]
    update-plots
    set elapsed-time elapsed-time + dt
    set iterations iterations + 1
    tick-advance dt
  ]
end 

; if any agents are within coalescence radius, merge into one agent

to check-for-collisions
  ask other actors [
    if realdist self myself <= CoalescenseRadius [
        merge self myself
    ]
  ]
end 

; Merge two agents into one.
; Note: the position of the merged agent is the position of the agent with the larger mass.
;       the color of the merged agent is the color of the agent with the larger mass.

to merge [ a b ] ;; a merges with with b
  set mergeTotMass mergeTotMass + mass + [mass] of b
  let mergemass mass
  ;; user-message (word "aself " [who] of a " bself/myself " [who] of b)
;;  if [mergewith] of a = [mergewith] of b [
;;    user-message (word "Merging with each other " [who] of a " " [who] of b)
;;  ]
  if mass > [mass] of b [
    ask b [
      set color [color] of a
      set xc [xc] of a
      set yc [yc] of a
    ]
  ]
  ask b [
      set mass mass + mergemass
      set massP massP + [massP] of a
      set shape "triangle"
      set size masstosize mass
  ]
  set mergeCount mergeCount + 1
  ask a [
;;    user-message (word "Turtle " [who] of a " is dead now")
    die
  ]
end 

to update-force ;; Turtle Procedure
  ;; This is recursive over all the actors, each turtle asks this of all other actors
  ;; Note: the force calculations are for all the other agents, not the asking agent, i.e., myself
  ;;       the force of myself on all other agents is set in this procedure.
  ask other actors with [ (realdist self myself) <= AIB ] [
    sum-its-force-on-me myself
  ]
end 

; The force calculations are done. 'it' is the asking agent.
; Note: The force adjustment control determines the force direction.

to sum-its-force-on-me [it] ;; Turtle Procedure
  let distsq vecdistsq it self
  let dist sqrt distsq
  let ab adotb it self
  let fxt 0
  let fyt 0
  if forceAdj != "Normal" [
    ifelse forceAdj = "AttractOnly" [
      set ab abs ab
    ][ ifelse forceAdj = "Repulse" [
      set ab ( - abs ab )
    ][ ifelse forceAdj = "NoRepulse" [
          if ab < 0 [
            set ab 0
          ]
        ][ ifelse forceAdj = "NoAttract" [
            if ab > 0 [
              set ab 0
            ]
          ][
            set ab ( - ab )
          ]
  ]]]]
  set fxt g * ( (( [xc] of it - xc ) / dist) *  ( [mass] of it ) * ab ) / ( (dist ^ DistanceExponent)  )
  set fyt g * ( (( [yc] of it - yc ) / dist) *  ( [mass] of it ) * ab ) / ( (dist ^ DistanceExponent)  )
  set fx fx + fxt
  set fy fy + fyt
  ifelse ab >= 0 [
    set attractive attractive + sqrt ( fxt ^ 2 + fyt ^ 2)
  ] [
    set repulsive repulsive + sqrt ( fxt ^ 2 + fyt ^ 2)
  ]
;;  if debug
;;  [ user-message (word "who " who " it= " it " adotb " ab " dist " distsq  " fxdir " fxdir " fydir " fydir " fx " fx " fy " fy) ]
end 

; The position is update for the agent depending on the forces on the agent.
; Note: the force is divided by the mass of the agent being updated. The mass is considered to be
;       its passive mass / inertia to the movement.

to update-position ;; Turtle Procedure
  ;; As our system is closed, we can safely recenter the center of mass to the origin.
  let stopq false
  set dxc fx * ( dt ^ 2) / massP
  set dyc fy * ( dt ^ 2) / massP
  let dist sqrt ( dxc ^ 2 + dyc ^ 2)
  if dist > maxdist [
    set maxdist dist
  ]
  let newxc (xc + dxc)
  let newyc (yc + dyc)
  if abs(newxc) > max-pxcor [
    set shape "ghost"
  ]
  if abs(newyc) > max-pycor [
    set shape "ghost"
  ]
  set xc newxc
  set yc newyc
;;  if debug [
;;    if newxc < min-pxcor or newxc > max-pxcor or newyc < min-pycor or newyc > max-pycor [
;;      user-message (word "up who " who " dxc dxy " dxc " " dyc " newxc newrxy " xc " " yc " xcor ycor " xcor " " ycor)
;;    ]
;;  ]
  adjust-position
end 

; set agent coordinates from coordinate variables used to do all the force calculations.

to adjust-position ;; Turtle Procedure
  if shape != "ghost" [
    setxy xc yc
  ]
end 

to show-force
  if maxforce != 0 [
      let poshift forcescale / maxforce
      let tx 0
      let ty 0
      ask actors [
        ;;user-message (word "maxforce poshift who " maxforce " " poshift " " who " xcor ycor " xcor " " ycor )
        ask out-fvec-neighbors [
          ;;user-message (word "fvecnbr" who " xcor ycor " xcor " " ycor "myself xcor ycor " [xcor] of myself " " [ycor] of myself " who of myself " [who] of myself)
          set tx ( [xcor] of myself ) + ( [fx] of myself ) * poshift
          set ty ( [ycor] of myself ) + ( [fy] of myself ) * poshift
          ifelse ( abs tx ) < max-pxcor [
            set xcor tx
          ] [
            ifelse xcor < 0 [
              set xcor min-pxcor
            ] [
              set xcor max-pxcor
            ]
          ]
          ifelse ( abs ty ) < max-pycor [
            set ycor ty
          ] [
            ifelse xcor < 0 [
              set ycor min-pycor
            ] [
              set ycor max-pycor
            ]
          ]

          ;;show-turtle
        ]
      ]
    ]
    ask fvecs [
      show-link
    ]
end 

; calculate the square of the distance between two agents

to-report vecdistsq [a b]
  report ([xc] of a - [xc] of b) ^ 2 + ([yc] of a - [yc] of b) ^ 2
end 

; calculate the a dot b value of two agents

to-report adotb [a b]
   if infprob < random 100 [
;    probdebug "infprob" a b
    report 0
  ]
  if ProbDist != "None" [
    if ProbDist = "AttributeDiff" [
      let cosval abs (( ([xc] of a * [xc] of b) + [yc] of a * [yc] of b )/( vecmag a * vecmag b))
      if cosval < random-float 1 [
;        probdebug "AttrDiff" a b
        report 0
      ]
    ]
    if ProbDist = "DistanceProb" [
      let dist realdist a b
      let prob abs (AIB - dist) / AIB
      if prob < random-float 1 [
 ;       probdebug "ProbDist" a b
        report 0
      ]
    ]
  ]
  report ( ([xc] of a * [xc] of b) + [yc] of a * [yc] of b )
end 


; How who is out of the loop for this iteration

to probdebug [ r a b ]
  if count actors <= 3 [
    print ( word r " Zero FaOnb for iteration " iterations " a " [who] of a " b " [who] of b)
  ]
end 


; calculate distance between two agents

to-report realdist [a b]
  report sqrt ( ( [xc] of a - [xc] of b) ^ 2 + ([yc] of a - [yc] of b) ^ 2)
end 

; calculate the force on an agent

to-report force-on-me [it]
  report sqrt ( [fx] of it ^ 2 + [fy] of it  ^ 2  )
end 

; convert mass to size parameter for displaying agents proportional to their size.
; Note: this is done on a log scale

to-report masstosize [m]
  report scale * masscale * log m 10
end 

; generate a random distribution within the min max
; parameters given with the given mean and standard deviation

to-report random-normal-in-bounds [ mid dev mmin mmax ]
  let result random-normal mid dev
  if result < mmin or result > mmax [
    set oobcount oobcount + 1
    report random-normal-in-bounds mid dev mmin mmax
  ]
  report result
end 

; generate an exponential distribution within the min / max
; range given with the given mean. Move half the results to
; the negative coordinates since the universe is -max to +max

to-report random-exponential-pos-in-bounds [ distmean mmin mmax ]
  let result random-exponential distmean
  if result < mmin or result > mmax [
      set oobcount oobcount + 1
      report random-exponential-pos-in-bounds distmean mmin mmax
  ]
  if random 2 = 1
      [ set result ( - result) ]
  report result
end 

; generate an exponential distribution within the min / max
; range given with the given mean.

to-report random-exponential-in-bounds [ distmean mmin mmax ]
  let result random-exponential distmean
  if result < mmin or result > mmax [
    set oobcount oobcount + 1
    report random-exponential-in-bounds distmean mmin mmax
  ]
  report result
end 

; calculate the magnitude of the given vector / agent

to-report vecmag [vec]
  report sqrt ( ([xc] of vec) ^ 2  + ([yc] of vec) ^ 2)
end 

; calculate the distance to be traveled by the agent calling
; with a dt of 1. set the global max if distance exceeds the current maximum
; also set the global maxforce for this iteration

to peakdist-calc
  if force-on-me self > maxforce [
    set maxforce force-on-me self
  ]
  set dxc  fx / massP
  set dyc  fy / massP
  let dist sqrt ( dxc ^ 2 + dyc ^ 2 )
  if dist > peakdist [
    set peakdist dist
  ]
end 

to doGeometry
  let rval Pradius
  while [ rval <= Prange ] [
    let n 0
    repeat Nsides [
      let txc nextVx Pxcenter rval Nsides n
      let tyc nextVy Pycenter rval Nsides n
      if abs(txc) < max-pxcor and abs(tyc) < max-pycor [
        create-actors 1 [
          set xc txc
          set yc tyc
          setxy txc tyc
          if track [
            pen-down
          ]
        ]
        if fill [
          dofill txc tyc rval n
        ]
      ]
      ;; user-message ( word "x y side cos sin" txc " " tyc " "  n  " " cos (360 * n / Nsides) )
      set n n + 1


    ]
    set rval rval + Pstep
    if Pstep = 0 [
      set rval Prange + 1
    ]
  ]
end 

to dofill [txc tyc rval nth]
  let f filldistance
  loop [
    let ntxc nextVx Pxcenter rval Nsides (nth + 1)
    let ntyc nextVy Pycenter rval Nsides (nth + 1)
    let nx txc + f * sin ( atan (ntxc - txc) (ntyc - tyc))
    let ny tyc + f * sin ( atan (ntyc - tyc) (ntxc - txc))
    if abs nx > max (list abs ntxc abs txc) or abs ny > max (list abs ntyc abs tyc) [ stop ]
    create-actors 1 [
      set xc nx
      set yc ny
      setxy nx ny
      if track [
        pen-down
      ]
      set f f + filldistance
    ]
  ]
end 

to-report nextVx [v rv sides nth]
  report v + rv * precision cos (360 * nth / Nsides) 12
end 

to-report nextVy [v rv sides nth]
  report v + rv * precision sin (360 * nth / Nsides) 12
end 

to meanlocs

  let masscount 0
  let distorigin 0
  set meanxloc 0
  set meanyloc 0
  set agentcount count actors
  set mominertia 0
;  Calculate the mass weighted mean x and y locations of all the agents
;  Calculate distance to the origin for each agent for the mean distance to the origin calc.
;  Calculate the total mass of all the agents to get the mean x,y location divisor.
;  Set mag (size), angle of each agent
  ask actors [
    set meanxloc meanxloc + ( xc * mass )
    set meanyloc meanyloc + ( yc * mass )
    set masscount masscount + mass
    set mag vecmag self
    set distorigin distorigin + mag
    set angle atan xc yc
    set mominertia mominertia + mass * (mag ^ 2)
  ]
  set meandistorigin distorigin / agentcount  ;; mean distance to the origin of all the agents
  set meanxloc meanxloc / masscount     ; mass weighted mean of x,y locations of all the agents
  set meanyloc meanyloc / masscount
end 

; Calculate means, standard deviations, etc. for display.

to meanlocation

  set groups count actors with [ shape = "triangle"  or  shape = "ghost" ]

  meanlocs

  ask cogs [
    set xcor meanxloc
    set ycor meanyloc
    set color 15 + ( 10 * int ( iterations / 400 ))
  ]

; Calculate mean distance to neighbors for all the agents
; Calculate mean distance to closest neighbor for all agents
; For each agent, store the distance to closest neighbor
  let mindist 0
  let dcnsum 0
  let tempdist 0
  let mymeandist 0
  set meandist 0
  ask actors [
    set mindist 10 * scale
    set mymeandist 0
    ; Calculate the distance to closest neighbor.
    ; Sum mean distance to others for each agent.
    ask other actors [
      set tempdist realdist self myself
      if tempdist < mindist [
        set mindist tempdist
      ]
      set mymeandist mymeandist + tempdist
    ]
    set dcn mindist     ; set distance to closest neighbor
    set dcnsum dcnsum + mindist  ; sum dcns for mean calcs
    ; Then divide by agentcount -1 to not include self) to gat the mean dist to all agents
    ifelse agentcount = 1 [
      set meandist 0
      set dcnsum 0
    ][
      ; Note that distance to self is 0 and is not counted in calculating the mean, hence agent count - 1
      set meandist meandist + ( mymeandist / ( agentcount - 1 ) )  ; sum each agents mean distance to neighbors
    ]
  ]
  ; Get the means across all agents.
  set meandist meandist / agentcount  ; get mean distance to neighbor across all agents
  set meandistclosestneighbor dcnsum / agentcount

  ; Calculate the standard deviations for x, y, and dist to closest neighbor
  set dcnsd 0
  set meanxsd 0
  set meanysd 0
  ask actors [
    set meanxsd meanxsd + ( xc - meanxloc ) ^ 2
    set meanysd meanysd + ( yc - meanyloc ) ^ 2
    set dcnsd dcnsd + ( meandistclosestneighbor - dcn ) ^ 2
  ]
  set meanxsd sqrt ( meanxsd / agentcount )
  set meanysd sqrt ( meanysd / agentcount )
  set dcnsd sqrt ( dcnsd / agentcount )
end 

;; Center of Mass

to recenter
  find-center-of-mass
  ask actors
  [ set xc (xc - center-of-mass-xc)
    set yc (yc - center-of-mass-yc)
    adjust-position
  ]
end 

to find-center-of-mass
  if any? actors
  [ set center-of-mass-xc sum [mass * xc] of actors / sum [mass] of actors
    set center-of-mass-yc sum [mass * yc] of actors / sum [mass] of actors
  ]
end 

; Record the view as a movie
;to movie
;  if record-view [
;    vid:save-recording "view.mp4"
;    vid:stop
;  ]
;  if record-interface [
;    vid:save-recording "interface.mp4"
;    vid:stop
;  ]
;end

; Record the interface as a movie
;to movie-init
;  if record-view [
;    vid:record-view
;  ]
;  if record-interface [
;    vid:record-interface
;  ]
;end


;Copyright 2020 Moody Ahmad, G Jordan Maclay.
;Creative Commons Attribution-NonCommercial-ShareAlike 4.0 International Public License
;License details at https://creativecommons.org/licenses/by-nc-sa/4.0/legalcode
;Note: For full disclosure: This model base was the N-Bodies model in the Netlogo Sample Models library under Chemistry and Physics -> Mechanics -> unverified -> N-Bodies. That
;was a starting point. The model has been modified almost completely from the starting point.

There are 8 versions of this model.

Uploaded by When Description Download
Moody Ahmad over 3 years ago Model updated for PLOS Paper submission Download this version
Moody Ahmad almost 4 years ago Removed video extension for web based version Download this version
Moody Ahmad almost 4 years ago Removed shell extension for running model on the web. Download this version
Moody Ahmad almost 4 years ago Removed profiler extensio so that the model can be run on the web. Download this version
Moody Ahmad about 4 years ago Changed agent color assignment to have darker colors for better visibility Download this version
Moody Ahmad about 4 years ago Updated info tab to correct documentation that referred to an older version of the model. Download this version
Moody Ahmad over 4 years ago Updated comments and copyright note Download this version
Moody Ahmad over 4 years ago Initial upload Download this version

Attached files

File Type Description Last updated
v2.23plos.png png Interface image over 3 years ago, by Moody Ahmad Download

This model does not have any ancestors.

This model does not have any descendants.