pgfplots: Trazar la función inversa (función de y)

pgfplots: Trazar la función inversa (función de y)

Estoy tratando de trazar elrelación-ramberg-osgoodpara un material específico con pgfplots. La relación describe la curva tensión-deformación, es decir, la tensión en función de la deformación. La relación en sí se define como la deformación en función de la tensión:

strain(stress)=stress/modulus+0.002*(stress/yield stress)^n

ya encontré unhiloque describe cómo trazar funciones inversas, así que traza x como función de y.

Sin embargo, todo lo que intenté resultó en un error.Dimensión demasiado grandepor TikZ,Unidad de medida ilegalcon fpu como eneste hiloo la función incorrecta con gnuplot.

Aquí están los MWE de las cosas que probé:

  • Pgfplots simples:

    \documentclass{standalone}
    \usepackage{pgfplots}
    \usepackage{siunitx}
    
    \pgfplotsset{compat=1.10}
    
    \begin{document}
    
    \pgfplotsset{stressstrainset/.style={%
    axis lines=center,
    xlabel={$\varepsilon$ $\left[\si{\percent}\right]$},
    ylabel={$\sigma$ $\left[\si{\MPa}\right]$},
    restrict x to domain=0:15,
    restrict y to domain=0:775,
    xmin=0.0, xmax=  15,
    ymin=0.0, ymax= 775,
    samples=100,
    }}
    
    \begin{tikzpicture}
    \pgfmathsetmacro\modulus{72400}
    \pgfmathsetmacro\yield{325}
    \begin{axis}[stressstrainset]
    \addplot[black] (x/\modulus+0.002*(x/\yield)^15,x);
    \end{axis}
    \end{tikzpicture}
    
    \end{document}
    

Resultados en:

! Dimension too large.
<to be read again> 
\relax 
l.21 \pgfmathsetmacro\modulus{72400}
  • diagramas de pgf con fpu:

    \documentclass{standalone}
    \usepackage{pgfplots}
    \usepackage{siunitx}
    
    \pgfplotsset{compat=1.10}
    
    \begin{document}
    
    \pgfplotsset{stressstrainset/.style={%
    axis lines=center,
    xlabel={$\varepsilon$ $\left[\si{\percent}\right]$},
    ylabel={$\sigma$ $\left[\si{\MPa}\right]$},
    restrict x to domain=0:15,
    restrict y to domain=0:775,
    xmin=0.0, xmax=  15,
    ymin=0.0, ymax= 775,
    samples=100,
    }}
    
    \begin{tikzpicture}
    \pgfkeys{/pgf/fpu=true}
    \pgfmathsetmacro\modulus{72400}
    \pgfkeys{/pgf/fpu=false}
    \pgfmathsetmacro\yield{325}
    \begin{axis}[stressstrainset]
    \addplot[black] (x/\modulus+0.002*(x/\yield)^15,x);
    \end{axis}
    \end{tikzpicture}
    
    \end{document}
    

Resultados en:

! Illegal unit of measure (pt inserted).
  • pgfplots con gnuplot:

    \documentclass{standalone}
    \usepackage{pgfplots}
    \usepackage{siunitx}
    
    \pgfplotsset{compat=1.10}
    
    \begin{document}
    
    \pgfplotsset{stressstrainset/.style={%
    axis lines=center,
    xlabel={$\varepsilon$ $\left[\si{\percent}\right]$},
    ylabel={$\sigma$ $\left[\si{\MPa}\right]$},
    restrict x to domain=0:15,
    restrict y to domain=0:775,
    xmin=0.0, xmax=  15,
    ymin=0.0, ymax= 775,
    samples=100,
    }}
    
    \begin{tikzpicture}
    \begin{axis}[stressstrainset]
    \addplot gnuplot [raw gnuplot,id=nfive, mark=none, draw=black]{
    set xrange  [0:15];
    modulus = 72400;
    yield   = 325;
    h(x)=(x/modulus+0.002*(x/yield)^15);
    plot h(x),x
    };
    \end{axis}
    \end{tikzpicture}
    
    \end{document}
    

Me da un resultado que obviamente es incorrecto.

Editar

También intenté usar GPa como unidad para el estrés, pero me gustaría configurar el gráfico en el sistema MPa ya que el resto de mi documento lo usa.

\documentclass{standalone}
\usepackage{pgfplots}
\usepackage{siunitx}

\pgfplotsset{compat=1.10}

\begin{document}

\pgfplotsset{stressstrainset/.style={%
axis lines=center,
xlabel={$\varepsilon$ $\left[-\right]$},
ylabel={$\sigma$ $\left[\si{\GPa}\right]$},
restrict x to domain=0:0.15,
restrict y to domain=0:0.775,
xmin=0.0, xmax=  0.15,
ymin=0.0, ymax= 0.775,
samples=1000,
}}

\begin{tikzpicture}
\pgfmathsetmacro\modulus{72.400}
\pgfmathsetmacro\yield{0.325}
\begin{axis}[stressstrainset]
\addplot[black] (x/\modulus+0.002*(x/\yield)^15,x);
\end{axis}
\end{tikzpicture}

\end{document}

Editar2

Gracias a la respuesta de @Christian, hay una versión en ejecución del gráfico. Sin embargo, descubrí que necesito definir las deformaciones, por lo tanto el eje x, no en porcentaje, sino en el valor decimal real para obtener el gráfico correcto.

\documentclass{standalone}
\usepackage{pgfplots}
\usepackage{siunitx}

\pgfplotsset{compat=1.10}

\begin{document}

\pgfplotsset{stressstrainset/.style={%
axis lines=center,
xlabel={$\varepsilon$ $\left[-\right]$},
ylabel={$\sigma$ $\left[\si{\MPa}\right]$},
domain=0:775,
xmin=0.0, xmax= 0.15,
ymin=0.0, ymax= 775,
samples=100,
}}

\begin{tikzpicture}
\def\modulus{72400}
\def\yield{325}
\begin{axis}[stressstrainset]
\addplot[gray, dashed] ({x/\modulus},x);
\addplot[black] ({x/\modulus+0.002*(x/\yield)^15},x);
\end{axis}
\end{tikzpicture}

Ahora nuevamente, está el problema de que recibo el error.

! Dimension too large.

para el segundo diagrama adicional, pero solo si el exponente es >10. ¿El valor se está volviendo demasiado pequeño?

¿Alguien puede explicar cómo puedo configurar este gráfico correctamente?

Respuesta1

Como ya se explicó en algún comentario, \pgfmathsetmacro{72400}PGF no es compatible (de hecho, mi sistema lo acepta sin problemas; aparentemente algo ha cambiado en PGF CVS).

Sin embargo, no es necesario \pgfmathsetmacrosimplemente declarar una constante; es mucho más sencillo de escribir \def\MACRO{<constant>}(o usar \newcommand\MACRO{<constant>}, que debería ser lo mismo).

Entonces necesitas asignar un domain. La(s) clave(s) restrict * to domainno son una definición de cómo muestrear los puntos; se pueden utilizar para excluir puntos ya muestreados de la región de interés. En su caso, definiría domain=775y omitiría el restrict * to domain.

Finalmente, las expresiones matemáticas en gráficos paramétricos necesitan llaves adicionales si contienen otras llaves redondas. En otras palabras, utilícelo ({x/\modulus+0.002*(x/\yield)^15},x)para evitar confusión con las llaves (TeX no puede equilibrarlas automáticamente, solo puede equilibrar las llaves).

Tomando esto en conjunto, llego a la siguiente modificación de su primer argumento:

\documentclass{standalone}
\usepackage{pgfplots}

\pgfplotsset{compat=1.10}

\begin{document}

\pgfplotsset{stressstrainset/.style={%
axis lines=center,
xlabel={$\varepsilon$},
ylabel={$\sigma$},
%restrict x to domain=0:15,
domain=0:775,
xmin=0.0, xmax=  15,
ymin=0.0, ymax= 775,
samples=100,
}}

\begin{tikzpicture}
\def\modulus{72400}
\def\yield{325}
\begin{axis}[stressstrainset]
\addplot[black] ({x/\modulus+0.002*(x/\yield)^15},x);
\end{axis}
\end{tikzpicture}

\end{document}

ingrese la descripción de la imagen aquí

Respuesta2

Esto es lo que funcionó para mí en TeX Live 2013:

\documentclass{standalone}
\usepackage{pgfplots}
\usepackage{siunitx}

\begin{document}

\pgfplotsset{stressstrainset/.style={%
axis lines=center,
xlabel={$\varepsilon$ $\left[\si{\percent}\right]$},
ylabel={$\sigma$ $\left[\si{\MPa}\right]$},
restrict x to domain=0:15,
restrict y to domain=0:0.775, % GPa
xmin=0.0, xmax=  15,
ymin=0.0, ymax= 0.775, % GPa
samples=1000,
%scaled y ticks=false,
yticklabels={0, 0, 200, 400, 600} % MPa
}}

\begin{tikzpicture}
\pgfmathsetmacro\modulus{72.400} % GPa
\pgfmathsetmacro\yield{0.325} % GPa
\begin{axis}[stressstrainset]
\addplot[black] (x/\modulus+0.002*(x/\yield)^15,x);
\end{axis}
\end{tikzpicture}

\end{document}

ingrese la descripción de la imagen aquí

Respuesta3

(Parcialmente resuelto.) ¡He dibujado una línea recta casi perfecta sin cambios significativos en la intersección con el eje Y! Incluso esos valores parecen sospechosos...

Bueno, no sé exactamente cómo configurar los parámetros para esta tarea en particular, pero no estaba limitado en los cálculos ya que Lua estaba huyendo. Podría resultar útil conocer este método para tareas similares a largo plazo. Lua puede incluso mejorarse con las bibliotecas BigNum y BigRat.http://oss.digirati.com.br/luabignum/. Me inspiré en este artículo,http://www.unirioja.es/cu/jvarona/downloads/numerical-methods-luatex.pdf, para intentar esta tarea independientemente de los resultados. Como ejercicio también enumeré las coordenadas como respuesta inmediata si los resultados son los que deberían ser.

%! lualatex inverse.tex
\documentclass[a4paper]{article}
\usepackage{pgfplots}
\pgfplotsset{compat=1.10}
\usepackage{siunitx}
\usepackage{luacode}
\parindent=0pt
\pagestyle{empty}

\begin{document}
\def\myxmin{0}
\def\myxmax{15}
\def\mysamples{100}
\def\mymodulus{72400} % /1000?
\def\myyield{325} % /1000?

\pgfplotsset{stressstrainset/.style={%
  axis lines=center,
  xlabel={Strain $\varepsilon$ $\left[\si{\percent}\right]$},
  ylabel={Stress $\sigma$ $\left[\si{\MPa}\right]$},
  restrict x to domain=0:\myxmax,
  restrict y to domain=0:775, % /1000?
  xmin=\myxmin, xmax=\myxmax,
  ymin=0.0, ymax=775, % /1000?
  samples=\mysamples,
  }}

\begin{luacode*}
-- Round me...
-- http://lua-users.org/wiki/SimpleRound
function round(num, idp)
  local mult=10^(idp or 0)
  return math.floor(num*mult+0.5)/mult
end

-- Compute me...
function computeme(xmin,xmax,samples,modulus,yield)
  local step=(xmax-xmin)/(samples-1)
  local x=xmin
  local y
  local mystring=""
  tex.sprint("\\begin{tikzpicture}")
  tex.sprint("\\begin{axis}[stressstrainset])")
  tex.sprint("\\addplot[black] coordinates {")
  for i=1,samples do
    y=1000000*(x/modulus+0.002*(x/yield)^15)
    mystring=mystring.."("..round(x,2)..","..round(y,2)..") "
    x=x+step
  end
tex.sprint(mystring) -- values in the graph
tex.sprint("};")
tex.sprint("\\end{axis}")
tex.sprint("\\end{tikzpicture}\\par")
tex.sprint(mystring) -- paper
end
\end{luacode*}

% Draw and show me...
\directlua{computeme(\myxmin, \myxmax, \mysamples, \mymodulus, \myyield)}
\end{document}

MWE

información relacionada