Point charges plot
fieldSolve[field_, varlist_, xi0_, tmax_, debug_: False] := Module[
  {xiVec, equationSet, t},
  If[Length[varlist] != Length[xi0], 
   Print["Number of variables must equal number of initial conditions\
\nUSAGE:\n" <> fieldSolve::usage]; Abort[]];
  xiVec = Through[varlist[t]];
  (* Below, Simplify[equationSet] would cost extra time 
    and doesn't help with the numerical solution, so   don't try to simplify. *)
  equationSet = Join[
    Thread[
     Map[D[#, t] &, xiVec] == 
      Normalize[field /. Thread[varlist -> xiVec]]
     ],
    Thread[
     (xiVec /. t -> 0) == xi0
     ]
    ];
  If[debug, 
   Print[Row[{"Numerically solving the system of equations\n\n", 
      TraditionalForm[(Simplify[equationSet] /. t -> "t") // 
        TableForm]}]]];
  (* This is where the differential equation is solved. 
  The Quiet[] command suppresses warning messages because numerical precision isn't crucial for our plotting purposes: *)
  Map[Head, First[xiVec /.
     Quiet[NDSolve[
       equationSet,
       xiVec,
       {t, 0, tmax}
       ]]], 2]
  ]   
fieldLinePlot[field_, varList_, seedList_, opts : OptionsPattern[]] :=
   Module[{sols, localVars, var, localField, plotOptions, 
    tubeFunction, tubePlotStyle, postProcess = {}}, 
   plotOptions = FilterRules[{opts}, Options[ParametricPlot3D]];
   tubeFunction = OptionValue["TubeFunction"];
   If[tubeFunction =!= None,
    tubePlotStyle = Cases[OptionValue[PlotStyle], Except[_Tube]];
    plotOptions = 
     FilterRules[plotOptions, 
      Except[{PlotStyle, ColorFunction, ColorFunctionScaling}]];
    postProcess = 
     Line[x_] :> 
      Join[tubePlotStyle, {CapForm["Butt"], 
        Tube[x, tubeFunction @@@ x]}]
    ];
   If[Length[seedList[[1, 1]]] != Length[varList], 
    Print["Number of variables must equal number of initial \
conditions\nUSAGE:\n" <> fieldLinePlot::usage]; Abort[]];
   localVars = Array[var, Length[varList]];
   localField = 
    ReleaseHold[
     Hold[field] /. 
      Thread[Map[HoldPattern, Unevaluated[varList]] -> localVars]];
   (*Assume that each element of seedList specifies a point AND the \
length of the field line:*)Show[
    Table[
     ParametricPlot3D[
         Evaluate[
          Through[#[t]]], {t, #[[1, 1, 1, 1]], #[[1, 1, 1, 2]]}, 
         Evaluate@Apply[Sequence, plotOptions]
         ] &[fieldSolve[
        localField, localVars, seedList[[i, 1]], seedList[[i, 2]]
        ]
       ] /. postProcess, {i, Length[seedList]}
     ]
    ]
   ];
Options[fieldLinePlot] = 
  Append[Options[ParametricPlot3D], "TubeFunction" -> None];
SetAttributes[fieldSolve, HoldAll];
f2[x_, y_,z_] := {x, y, z}/Norm[{x, y, z}]^3 - ({x, y, z} - {1, 1, 1})/
   Norm[{x, y, z} - {1, 1, 1}]^3
seedList = 
  With[{vertices = .1 N[PolyhedronData["Icosahedron"][[1, 1]]]}, 
   Join[Map[{#, 2} &, vertices], 
    Map[{# + {1, 1, 1}, -2} &, vertices]]];
fieldLinePlot[f2[x, y, z], {x, y, z}, seedList, 
 PlotStyle -> {Orange, Directive["Roughness"->0., "Specularity"->White, "SpecularityIntensity"->10000]}, PlotRange -> All, Lighting->None, Epilog->{
   PointLight[White, 5 {1,1,1}, 100],
   SpotLight[Red, 5 {1,1,1}, 100],
   SpotLight[Green, 5 {1,-1,1}, 100],
   SpotLight[Blue, 5 {-1,1,1}, 100],
   HemisphereLight[LightBlue, Black, 0.1]
  },
 "TubeFunction" -> 
  Function[{x, y, z}, Quiet[Clip[Norm[f2[x, y, z]], {2, 40}]/300]], 
 Background -> Black, ImageSize->500]