PageRenderTime 23ms CodeModel.GetById 24ms RepoModel.GetById 0ms app.codeStats 0ms

/tags/cvs_final/octave-forge/extra/civil/inst/nlnewmark.m

#
MATLAB | 188 lines | 179 code | 8 blank | 1 comment | 6 complexity | 8c55ef118d9876d794f1f2dff90133fd MD5 | raw file
Possible License(s): GPL-2.0, BSD-3-Clause, LGPL-2.1, GPL-3.0, LGPL-3.0
  1. ## Copyright (C) 2000 Matthew W. Roberts. All rights reserved.
  2. ##
  3. ## This file is part of Octave.
  4. ##
  5. ## Octave is free software; you can redistribute it and/or modify it
  6. ## under the terms of the GNU General Public License as published by the
  7. ## Free Software Foundation; either version 2, or (at your option) any
  8. ## later version.
  9. ##
  10. ## Octave is distributed in the hope that it will be useful, but WITHOUT
  11. ## ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  12. ## FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
  13. ## for more details.
  14. ##
  15. ## You should have received a copy of the GNU General Public License
  16. ## along with Octave; see the file COPYING. If not, write to the Free
  17. ## Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02111 USA.
  18. ## -*- texinfo -*-
  19. ## @deftypefn {Function File} {@var{x} =} nlnewmark(@var{m}, @var{c}, @var{q}, @var{f}, @var{dt}, @var{x0} = 0, @var{x'0} = 0, @var{alpha} = 1/2, @var{beta} = 1/4, @var{flags} = "")
  20. ## Computes the solution of non-linear second-order differential equations of the form
  21. ##
  22. ## @example
  23. ## @var{m} @var{x}'' + @var{c} @var{x}' + @var{q}(@var{x}, @var{x}', @var{x}'') = @var{f}
  24. ## @end example
  25. ##
  26. ## where @var{x}' denotes the first time derivative of @var{x} and @var{q} is
  27. ## a non-linear function.
  28. ##
  29. ## If the function is called without the assigning a return value
  30. ## then @var{x} is plotted versus time.
  31. ##
  32. ## @strong{Inputs}
  33. ##
  34. ## @table @var
  35. ## @item m
  36. ## The mass of the body.
  37. ## @item c
  38. ## Viscous damping of the system.
  39. ## @item q
  40. ## The name of a function
  41. ## that returns the value of the resisting force for a given
  42. ## displacement. The form of Q must be:
  43. ##
  44. ## @example
  45. ## @var{F} = Q( @var{x})
  46. ## @end example
  47. ##
  48. ## where @var{F} is the restoring force for the state vector @var{x}
  49. ## = [@var{u}, @var{u'}, @var{u''}]; displacement
  50. ## (@var{u}), velocity (@var{u'}), and acceleration.
  51. ## @item f
  52. ## The forcing function as a time sampled or impulse vector
  53. ## (see @strong{Special Cases}).
  54. ## @item dt
  55. ## The time step -- assumed to be constant
  56. ## @item x0
  57. ## Initial displacement, default is zero
  58. ## @item x'0
  59. ## Initial velocity, default is zero
  60. ## @item alpha
  61. ## Alpha Coefficient -- Controls "artificial damping" of the system.
  62. ## Unless you have a really good reason, this should be 1/2 which is
  63. ## the default.
  64. ## @item beta
  65. ## Beta Coefficient -- This coefficient is used to estimate the form of the
  66. ## system acceleration between time steps. Values between 1/4 and 1/6 are
  67. ## common. The default is 1/4 which is unconditionally stable.
  68. ## @item flags
  69. ## A string value which defines special cases. The cases are defined by
  70. ## unique characters as explained in @strong{Special Cases} below.
  71. ## @end table
  72. ##
  73. ## @strong{Outputs}
  74. ##
  75. ## @table @var
  76. ## @item x
  77. ## Matrix of size (3, @code{length(@var{f})}) with time series of displacement
  78. ## (@var{x}(1,:)), velocity (@var{x}(2,:)), and acceleration (@var{x}(3,:))
  79. ## @end table
  80. ##
  81. ## @strong{Special Cases}
  82. ##
  83. ## The @var{flags} variable is used to define special cases of analysis as
  84. ## follows.
  85. ##
  86. ## "i" - Impulse forcing function. The forcing function, @var{f} is a
  87. ## vector of impulses instead of a sampled time history.
  88. ## "n" - The stiffness is non-linear. In this case, @var{k} is a string
  89. ## which contains the name of a function defining the non-linear
  90. ## stiffness.
  91. ##
  92. ## @end deftypefn
  93. ## Author: Matthew W. Roberts
  94. ## Created: May, 2000
  95. function x = nlnewmark( M, C, Q, f, dt, u0, v0, alpha, beta, flags)
  96. global nlnewmark_status;
  97. # Take care of unititalized input variables
  98. if( nargin < 6)
  99. u0 = 0;
  100. endif
  101. if( nargin < 7)
  102. v0 = 0;
  103. endif
  104. if( nargin < 8)
  105. alpha = 0.5;
  106. endif
  107. if( nargin < 9)
  108. beta = 0.25;
  109. endif
  110. if( nargin < 10)
  111. flags = "";
  112. endif
  113. # check for flags
  114. if( findstr( flags, "i"))
  115. _local_impulse = 1; # local variable
  116. else
  117. _local_impulse = 0;
  118. endif
  119. # xxBEGINxx
  120. # initialize x
  121. x = zeros( 3, length(f));
  122. x(1,1) = u0;
  123. x(2,1) = v0;
  124. # compute the initial acceleration
  125. if( _local_impulse)
  126. # an initial impulse has the effect of instantaneously changing
  127. # the initial velocity.
  128. v0 = v0 + f(1)/M;
  129. x(2,1) = v0;
  130. # Now, initial acceleration comes from solving m*a0 + c*v0 + Q = 0
  131. ## :FIXME: here I'm assuming that the acceleration is not used in Q
  132. x(3,1) = ( - C * v0 - feval( Q, [u0, v0, 0]) ) / M;
  133. else
  134. # Compute a0 from m*a0 + c*v0 + Q = f0
  135. ## :FIXME: here I'm assuming that the acceleration is not used in Q
  136. x(3,1) = ( f(1) - C * v0 - feval( Q, [u0, v0, 0]) ) / M;
  137. endif
  138. # define some constants so that we won't need to recalculate each loop:
  139. c1 = dt^2 * (0.5 - beta);
  140. c2 = dt * (1 - alpha);
  141. # These need to be known by __nlnewmark_fcn__
  142. nlnewmark_status.a1 = dt^2*beta;
  143. nlnewmark_status.a2 = dt*alpha;
  144. nlnewmark_status.C = C;
  145. nlnewmark_status.M = M;
  146. nlnewmark_status.Q = Q;
  147. rhs(3) = 0; # default value - always this for impulse
  148. for i = 2:length(f)
  149. % create the rhs
  150. nlnewmark_status.rhs(1) = x(1, i-1) + dt * x(2, i-1) + c1 * x(3, i-1);
  151. nlnewmark_status.rhs(2) = x(2, i-1) + c2 * x(3, i-1);
  152. if( ! _local_impulse)
  153. nlnewmark_status.rhs(3) = f(i);
  154. endif
  155. # solve for x - using previous value as starting guess...
  156. [x(:, i), info] = fsolve( "__nlnewmark_fcn__",
  157. [x(1, i-1); x(2, i-1); x(3, i-1)]);
  158. info
  159. # add the impulse effect...
  160. if( _local_impulse)
  161. x(2,i) = x(2,i) + f(i)/M;
  162. endif
  163. endfor
  164. if( nargout < 1)
  165. t = 0:dt:(length(f)-1)*dt;
  166. length(t);
  167. plot( t, x(1,:));
  168. endif
  169. endfunction