pgfplots: Plotar função inversa (função de y)

pgfplots: Plotar função inversa (função de y)

Estou tentando traçar oRelacionamento Ramberg-Osgoodpara um material específico com pgfplots. A relação descreve a curva tensão-deformação, ou seja, a tensão em função da deformação. A relação em si é definida como a deformação em função da tensão:

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

Eu já encontrei umfioque descreve a plotagem de funções inversas, então plote x como uma função de y.

No entanto, tudo o que tentei resultou em erro, sejaDimensão muito grandepor TikZ,Unidade de medida ilegalcom fpu como emeste tópicoou a função errada com o gnuplot.

Aqui estão os MWEs para as coisas que tentei:

  • 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}
    

Resulta em:

! Dimension too large.
<to be read again> 
\relax 
l.21 \pgfmathsetmacro\modulus{72400}
  • pgfplots com 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}
    

Resulta em:

! Illegal unit of measure (pt inserted).
  • pgfplots com 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 dá um resultado que está obviamente errado.

Editar

Também tentei usar o GPa como unidade de tensão, mas gostaria de configurar o gráfico no MPa-System, pois o restante do meu documento o utiliza.

\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

Graças à resposta de @Christian, existe uma versão do gráfico em execução. Porém, descobri que preciso definir as deformações, portanto o eixo x, não em porcentagem, mas no valor decimal real para obter o gráfico correto.

\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}

Agora, novamente, há o problema de eu receber o erro

! Dimension too large.

para o segundo addplot, mas apenas se o expoente for >10. O valor está ficando muito pequeno?

Alguém pode explicar como posso configurar este gráfico corretamente?

Responder1

Como já explicado em algum comentário, \pgfmathsetmacro{72400}não é suportado pelo PGF (na verdade, meu sistema aceita sem problemas - aparentemente algo mudou no PGF CVS).

Entretanto, você não precisa \pgfmathsetmacroapenas declarar uma constante; é muito mais simples escrever \def\MACRO{<constant>}(ou usar \newcommand\MACRO{<constant>}o que deve ser igual).

Então você precisa atribuir um arquivo domain. A(s) chave(s) restrict * to domainnão define(m) como amostrar pontos; eles podem ser usados ​​para excluir pontos já amostrados da região de interesse. No seu caso, você definiria domain=775e omitiria o restrict * to domain.

Finalmente, as expressões matemáticas em gráficos paramétricos precisam de chaves extras se contiverem outras chaves. Em outras palavras, use ({x/\modulus+0.002*(x/\yield)^15},x)para evitar confusão com os colchetes redondos (o TeX não pode equilibrá-los automaticamente, ele só pode equilibrar os colchetes).

Juntando tudo isso, chego à seguinte modificação do seu primeiro enredo:

\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}

insira a descrição da imagem aqui

Responder2

Aqui está o que funcionou para mim no 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}

insira a descrição da imagem aqui

Responder3

(Parcialmente resolvido.) Desenhei uma linha reta quase perfeita sem alteração significativa na interceptação y! Mesmo esses valores parecem suspeitos...

Bem, não sei exatamente como definir os parâmetros para esta tarefa em particular, mas não fiquei limitado nos cálculos porque Lua estava em fuga. Pode ser útil saber desta forma para tarefas semelhantes a longo prazo. Lua pode ser ainda melhorada pelas bibliotecas BigNum e BigRat,http://oss.digirati.com.br/luabignum/. Me inspirei neste artigo,http://www.unirioja.es/cu/jvarona/downloads/numerical-methods-luatex.pdf, para tentar esta tarefa independentemente dos resultados. Como exercício, também listei as coordenadas como um feedback imediato se os resultados forem o que deveriam 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

informação relacionada