class_docstr: A Truss is an assembly of members such as beams,
  connected by nodes, that create a rigid structure.
  In engineering, a truss is a structure that
  consists of two-force members only.
  
  Trusses are extremely important in engineering applications
  and can be seen in numerous real-world applications like bridges.
  
  Examples
  ========
  
  There is a Truss consisting of four nodes and five
  members connecting the nodes. A force P acts
  downward on the node D and there also exist pinned
  and roller joints on the nodes A and B respectively.
  
  .. image:: truss_example.png
  
  >>> from sympy.physics.continuum_mechanics.truss import Truss
  >>> t = Truss()
  >>> t.add_node(("node_1", 0, 0), ("node_2", 6, 0), ("node_3", 2, 2), ("node_4", 2, 0))
  >>> t.add_member(("member_1", "node_1", "node_4"), ("member_2", "node_2", "node_4"), ("member_3", "node_1", "node_3"))
  >>> t.add_member(("member_4", "node_2", "node_3"), ("member_5", "node_3", "node_4"))
  >>> t.apply_load(("node_4", 10, 270))
  >>> t.apply_support(("node_1", "pinned"), ("node_2", "roller"))
docstr: This method solves for all reaction forces of all supports and all internal forces
  of all the members in the truss, provided the Truss is solvable.
  
  A Truss is solvable if the following condition is met,
  
  2n >= r + m
  
  Where n is the number of nodes, r is the number of reaction forces, where each pinned
  support has 2 reaction forces and each roller has 1, and m is the number of members.
  
  The given condition is derived from the fact that a system of equations is solvable
  only when the number of variables is lesser than or equal to the number of equations.
  Equilibrium Equations in x and y directions give two equations per node giving 2n number
  equations. However, the truss needs to be stable as well and may be unstable if 2n > r + m.
  The number of variables is simply the sum of the number of reaction forces and member
  forces.
  
  .. note::
     The sign convention for the internal forces present in a member revolves around whether each
     force is compressive or tensile. While forming equations for each node, internal force due
     to a member on the node is assumed to be away from the node i.e. each force is assumed to
     be compressive by default. Hence, a positive value for an internal force implies the
     presence of compressive force in the member and a negative value implies a tensile force.
  
  Examples
  ========
  
  >>> from sympy.physics.continuum_mechanics.truss import Truss
  >>> t = Truss()
  >>> t.add_node(("node_1", 0, 0), ("node_2", 6, 0), ("node_3", 2, 2), ("node_4", 2, 0))
  >>> t.add_member(("member_1", "node_1", "node_4"), ("member_2", "node_2", "node_4"), ("member_3", "node_1", "node_3"))
  >>> t.add_member(("member_4", "node_2", "node_3"), ("member_5", "node_3", "node_4"))
  >>> t.apply_load(("node_4", 10, 270))
  >>> t.apply_support(("node_1", "pinned"), ("node_2", "roller"))
  >>> t.solve()
  >>> t.reaction_loads
  {'R_node_1_x': 0, 'R_node_1_y': 20/3, 'R_node_2_y': 10/3}
  >>> t.internal_forces
  {'member_1': 20/3, 'member_2': 20/3, 'member_3': -20*sqrt(2)/3, 'member_4': -10*sqrt(5)/3, 'member_5': 10}
docstr_tok: ["This","method","solves","for","all","reaction","forces","of","all","supports","and","all","internal","forces","of","all","the","members","in","the","truss",",","provided","the","Truss","is","solvable",".","A","Truss","is","solvable","if","the","following","condition","is","met",",","2n",">","=","r","+","m","Where","n","is","the","number","of","nodes",",","r","is","the","number","of","reaction","forces",",","where","each","pinned","support","has","2","reaction","forces","and","each","roller","has","1",",","and","m","is","the","number","of","members",".","The","given","condition","is","derived","from","the","fact","that","a","system","of","equations","is","solvable","only","when","the","number","of","variables","is","lesser","than","or","equal","to","the","number","of","equations",".","Equilibrium","Equations","in","x","and","y","directions","give","two","equations","per","node","giving","2n","number","equations",".","However",",","the","truss","needs","to","be","stable","as","well","and","may","be","unstable","if","2n",">","r","+","m.","The","number","of","variables","is","simply","the","sum","of","the","number","of","reaction","forces","and","member","forces",".","..","note",":",":","The","sign","convention","for","the","internal","forces","present","in","a","member","revolves","around","whether","each","force","is","compressive","or","tensile",".","While","forming","equations","for","each","node",",","internal","force","due","to","a","member","on","the","node","is","assumed","to","be","away","from","the","node","i.e",".","each","force","is","assumed","to","be","compressive","by","default",".","Hence",",","a","positive","value","for","an","internal","force","implies","the","presence","of","compressive","force","in","the","member","and","a","negative","value","implies","a","tensile","force",".","Examples","========",">",">",">","from","sympy.physics.continuum_mechanics.truss","import","Truss",">",">",">","t","=","Truss","(",")",">",">",">","t.add_node","(","(","``","node_1","''",",","0",",","0",")",",","(","``","node_2","''",",","6",",","0",")",",","(","``","node_3","''",",","2",",","2",")",",","(","``","node_4","''",",","2",",","0",")",")",">",">",">","t.add_member","(","(","``","member_1","''",",","``","node_1","''",",","``","node_4","''",")",",","(","``","member_2","''",",","``","node_2","''",",","``","node_4","''",")",",","(","``","member_3","''",",","``","node_1","''",",","``","node_3","''",")",")",">",">",">","t.add_member","(","(","``","member_4","''",",","``","node_2","''",",","``","node_3","''",")",",","(","``","member_5","''",",","``","node_3","''",",","``","node_4","''",")",")",">",">",">","t.apply_load","(","(","``","node_4","''",",","10",",","270",")",")",">",">",">","t.apply_support","(","(","``","node_1","''",",","``","pinned","''",")",",","(","``","node_2","''",",","``","roller","''",")",")",">",">",">","t.solve","(",")",">",">",">","t.reaction_loads","{","'R_node_1_x","'",":","0",",","'R_node_1_y","'",":","20\/3",",","'R_node_2_y","'",":","10\/3","}",">",">",">","t.internal_forces","{","'member_1","'",":","20\/3",",","'member_2","'",":","20\/3",",","'member_3","'",":","-20","*","sqrt","(","2",")","\/3",",","'member_4","'",":","-10","*","sqrt","(","5",")","\/3",",","'member_5","'",":","10","}"]
code: def solve(self):
      """
      This method solves for all reaction forces of all supports and all internal forces
      of all the members in the truss, provided the Truss is solvable.
  
      A Truss is solvable if the following condition is met,
  
      2n >= r + m
  
      Where n is the number of nodes, r is the number of reaction forces, where each pinned
      support has 2 reaction forces and each roller has 1, and m is the number of members.
  
      The given condition is derived from the fact that a system of equations is solvable
      only when the number of variables is lesser than or equal to the number of equations.
      Equilibrium Equations in x and y directions give two equations per node giving 2n number
      equations. However, the truss needs to be stable as well and may be unstable if 2n > r + m.
      The number of variables is simply the sum of the number of reaction forces and member
      forces.
  
      .. note::
         The sign convention for the internal forces present in a member revolves around whether each
         force is compressive or tensile. While forming equations for each node, internal force due
         to a member on the node is assumed to be away from the node i.e. each force is assumed to
         be compressive by default. Hence, a positive value for an internal force implies the
         presence of compressive force in the member and a negative value implies a tensile force.
  
      Examples
      ========
  
      >>> from sympy.physics.continuum_mechanics.truss import Truss
      >>> t = Truss()
      >>> t.add_node(("node_1", 0, 0), ("node_2", 6, 0), ("node_3", 2, 2), ("node_4", 2, 0))
      >>> t.add_member(("member_1", "node_1", "node_4"), ("member_2", "node_2", "node_4"), ("member_3", "node_1", "node_3"))
      >>> t.add_member(("member_4", "node_2", "node_3"), ("member_5", "node_3", "node_4"))
      >>> t.apply_load(("node_4", 10, 270))
      >>> t.apply_support(("node_1", "pinned"), ("node_2", "roller"))
      >>> t.solve()
      >>> t.reaction_loads
      {'R_node_1_x': 0, 'R_node_1_y': 20/3, 'R_node_2_y': 10/3}
      >>> t.internal_forces
      {'member_1': 20/3, 'member_2': 20/3, 'member_3': -20*sqrt(2)/3, 'member_4': -10*sqrt(5)/3, 'member_5': 10}
      """
      count_reaction_loads = 0
      for node in self._nodes:
          if node[0] in self._supports:
              if self._supports[node[0]] == "pinned":
                  count_reaction_loads += 2
              elif self._supports[node[0]] == "roller":
                  count_reaction_loads += 1
      if (
          2 * len(self._nodes)
          != len(self._members) + count_reaction_loads
      ):
          raise ValueError("The given truss cannot be solved")
      coefficients_matrix = [
          [0 for i in range(2 * len(self._nodes))]
          for j in range(2 * len(self._nodes))
      ]
      load_matrix = zeros(2 * len(self.nodes), 1)
      load_matrix_row = 0
      for node in self._nodes:
          if node[0] in self._loads:
              for load in self._loads[node[0]]:
                  if load[0] != Symbol(
                      "R_" + str(node[0]) + "_x"
                  ) and load[0] != Symbol("R_" + str(node[0]) + "_y"):
                      load_matrix[load_matrix_row] -= load[0] * cos(
                          pi * load[1] / 180
                      )
                      load_matrix[load_matrix_row + 1] -= load[0] * sin(
                          pi * load[1] / 180
                      )
          load_matrix_row += 2
      cols = 0
      row = 0
      for node in self._nodes:
          if node[0] in self._supports:
              if self._supports[node[0]] == "pinned":
                  coefficients_matrix[row][cols] += 1
                  coefficients_matrix[row + 1][cols + 1] += 1
                  cols += 2
              elif self._supports[node[0]] == "roller":
                  coefficients_matrix[row + 1][cols] += 1
                  cols += 1
          row += 2
      for member in self._members:
          start = self._members[member][0]
          end = self._members[member][1]
          length = sqrt(
              (
                  self._node_coordinates[start][0]
                  - self._node_coordinates[end][0]
              )
              ** 2
              + (
                  self._node_coordinates[start][1]
                  - self._node_coordinates[end][1]
              )
              ** 2
          )
          start_index = self._node_labels.index(start)
          end_index = self._node_labels.index(end)
          horizontal_component_start = (
              self._node_coordinates[end][0]
              - self._node_coordinates[start][0]
          ) / length
          vertical_component_start = (
              self._node_coordinates[end][1]
              - self._node_coordinates[start][1]
          ) / length
          horizontal_component_end = (
              self._node_coordinates[start][0]
              - self._node_coordinates[end][0]
          ) / length
          vertical_component_end = (
              self._node_coordinates[start][1]
              - self._node_coordinates[end][1]
          ) / length
          coefficients_matrix[start_index * 2][
              cols
          ] += horizontal_component_start
          coefficients_matrix[start_index * 2 + 1][
              cols
          ] += vertical_component_start
          coefficients_matrix[end_index * 2][
              cols
          ] += horizontal_component_end
          coefficients_matrix[end_index * 2 + 1][
              cols
          ] += vertical_component_end
          cols += 1
      forces_matrix = (Matrix(coefficients_matrix) ** -1) * load_matrix
      self._reaction_loads = {}
      i = 0
      min_load = inf
      for node in self._nodes:
          if node[0] in self._loads:
              for load in self._loads[node[0]]:
                  if type(load[0]) not in [Symbol, Mul, Add]:
                      min_load = min(min_load, load[0])
      for j in range(len(forces_matrix)):
          if type(forces_matrix[j]) not in [Symbol, Mul, Add]:
              if abs(forces_matrix[j] / min_load) < 1e-10:
                  forces_matrix[j] = 0
      for node in self._nodes:
          if node[0] in self._supports:
              if self._supports[node[0]] == "pinned":
                  self._reaction_loads[
                      "R_" + str(node[0]) + "_x"
                  ] = forces_matrix[i]
                  self._reaction_loads[
                      "R_" + str(node[0]) + "_y"
                  ] = forces_matrix[i + 1]
                  i += 2
              elif self._supports[node[0]] == "roller":
                  self._reaction_loads[
                      "R_" + str(node[0]) + "_y"
                  ] = forces_matrix[i]
                  i += 1
      for member in self._members:
          self._internal_forces[member] = forces_matrix[i]
          i += 1
      return
  
imports: from cmath import atan, inf
  from sympy.core.add import Add
  from sympy.core.evalf import INF
  from sympy.core.mul import Mul
  from sympy.core.symbol import Symbol
  from sympy.core.sympify import sympify
  from sympy import Matrix, pi
  from sympy.external.importtools import import_module
  from sympy.functions.elementary.miscellaneous import sqrt
  from sympy.matrices.dense import zeros
  import math
  from sympy.physics.units.quantities import Quantity
  from sympy.plotting import plot
  from sympy.utilities.decorator import doctest_depends_on
  from sympy import sin, cos
label_desc: Use image node_id 21 for calling the Truss obj's underlying member method code with example usage: obj.solve() without return types