Ok, ora è tutto molto più chiaro e il codice è partito e ora funziona bene.
Ho provato a cimentarmi con un problema simile:
$ { ( (d^2 u)/dx^2 +g/k=0),( u(0)=u_0 ),( (d u)/dx(0)=-q_0/(k(u_0)) ):} $
$ q_0 $ è una costante (fisicamente è il flusso termico in ingresso del corpo). $q(x)=-k*(du)/(x)$ dove $u$ è la temperatura (ma questo ci interessa meno).
Tutti i termini noti e il $ k $ polinomiale sono sempre gli stessi come li ho definiti nelle risposte precedenti. Per quella questione del nodo fantasma ho usato un approccio diverso ma anche usando la definizione di nodo fantasma trovata in internet arrivo allo stesso risultato. Tramite lo sviluppo in serie di Taylor al secondo ordine posso scrivere il nodo $2$ in questo modo:
$ u_2 = u_1+(du)/(dx)(0)*Delta x +1/2*(d^2u)/(dx^2)(0)*Delta x^2 $
Sostituendo:
$ { ( (du)/(dx)(0)=-(q(0))/(k(u0)) ),( (d^2u)/(dx^2)(0)=-g/(k(u_0)) ):} $
La prima delle due viene dalle BC, mentre la seconda viene dall'equazione differenziale. Fatto questo si può scrivere per il nodo $2$:
$ u_2=u_0-q_0/(k(u(0)))*Delta x-1/2*g/(k(u_0))*Delta x^2 $
Ho quindi trovato una relazione che mi permette di calcolare $u_2$. Per quanto riguarda il codice ho tenuto il tuo schema, facendo qualche piccola modifica sulle condizioni al contorno, che ovviamente dovranno essere imposte sui nodi $ 1 $ e $ 2 $ invece che sui nodi $ 1 $ ed $ m $.
Questo è il codice:
- Codice:
%CODICE LASTRA PIANA 1D, GENERAZIONE,
%TEMPERATURA IMPOSTA IN INGRESSO E FLUSSO IMPOSTO IN INGRESSO
%EQUAZIONE: d2T/dx2 +g/k=0 con k=k0+k1*T
clear
clc
L=1; %lunghezza
m=50; %numero nodi
h=L/m; %intervallo spaziale
T0=5; %temperatura in x=0
q0=0; %flusso termico in x=0
g=0; %termine di generazione
k0=100; %primo termine della polinomiale per la conduttività termica: k=k0+aT
k1=20; %coefficiente della T
%MATRICE CHE DISCRETIZZA LA DERIVATA SECONDA
A=toeplitz(sparse([1,1],[1,2],[-2,1]/h^2,1,m));
I=speye(m);
%BOUNDARY CONDITIONS
A(1,1:2)=[1 0];
A(2,1:3)=[-1 1 0];
I(1,1)=0; I(2,2)=0;
b=zeros(m,1);
b(1)= -g/k0 - T0;
b(2)= -g/k0 + q0/(k0+k1*T0)*h + 1/2*g/(k0+k1*T0)*h^2;
F=@(u) A*u + g./(k0+k1.*I*u) + b;
JF=@(u) A-k1.*g.*spdiags([0;0;1./((k0+k1.*u(3:m))).^2],0,m,m);
%Newton:
tol=(h^2); %diff finite secondo ordine
u0=ones(m,1);
res=-JF(u0)\F(u0);
iter=0;
maxit=50;
while (norm(res,inf)>tol) & (iter<maxit)
iter=iter+1;
u0=u0+res;
res=-JF(u0)\F(u0);
end
u=u0+res;
x=linspace(0,L,m);
plot(x,u0)
A me sembra uguale identico a quello scritto con le condizioni di prima (che funziona), mentre questo gira (mi sembra che calcoli la funzione al nodo $ 2 $ in modo corretto) ma il resto del calcolo è sicuramente sbagliato.
Così di primo impatto mi verrebbe da pensare che c'è qualche errore nella funzione o nello Jacobiano, ma non vedo davvero niente di strano (ed è tutto il giorno che ci lavoro
). Te noti niente di sbagliato?