/* Last edited on 2011-05-16 16:59:04 by stolfilocal */ /*************************************************************************** * Copyright (C) 2009 by Douglas Castro * * douglas@ime.unicamp.br * * Last edited on 2009-10-27 15:55:20 by stolfilocal * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; if not, write to the * * Free Software Foundation, Inc., * * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * ***************************************************************************/ #ifdef HAVE_CONFIG_H #include #endif #define _GNU_SOURCE #include #include #include #include #include #include "arvore.h" #include "jsmath.h" #include "bool.h" #include "affirm.h" #include "definicoes.h" #include "inicializa.h" #include "interp_integ.h" #include "gnuplot_i.h" #include "imprime.h" #include "timestep.h" #include "plota.h" #include "amr.h" #include "bases.h" #include "jstime.h" #define DRAW_STEP 50 /* Desenhar a arvore a cada {DRAW_STEP} iteracoes. */ #define PLOT_STEP 50 /* Plotar a cada {PLOT_STEP} iteracoes. */ #define OUT_PREFIX "out" #define OUT_PREFIX2 "outv" #define OUT_PREFIX3 "outw" void evoluiRK2(int d, bool_t op, bool_t ow, int N, int niv_tot, int tp, double eps, double Dt, double xmin[], double xmax[], VNo pac[], Funcao f, Fluxo flx, bool_t haar, bool_t podar); void evoluiRK3(int d, bool_t op, bool_t ow, int N, int niv_tot, int tp, double eps, double Dt, double xmin[], double xmax[], VNo pac[], Funcao f, Fluxo flx, bool_t haar, bool_t podar); double *read_vector(FILE *rd); int main(int argc, char *argv[]) { bool_t op = FALSE; // ordem de previsao T <--> 4 , F <--> 2 bool_t ow = FALSE; // ordem de previsao weno T <--> 3 , F <--> 2 //int d = 3; //int d = 2; /* Dimensao da grade. */ int d = 1; /* Dimensao da grade. */ double xmin[d]; /* Coords inferiores da celula raiz. */ double xmax[d]; /* Coords superiores da celula raiz. */ int i; for (i = 0; i < d; i++) { xmin[i] = -1.0; xmax[i] = +1.0; } int niv_max = d*10; /* Nivel maximo sem contar camada de seguranca. */ int niv_tot = niv_max+1; /* Nivel maximo incluindo camada de seguranca. */ int tp = op ? 9 : 5; /* Tamanho do pacote em cada dimensao. */ int tm = ipow(tp, d); /* Tamanho total de um pacote. */ int kc = tm/2; /* Indice do elemento central do pacote. */ //Funcao *u0 = &condicaoinicial; /* Funcao de {x} que define o estado para {t=0}. */ //Funcao *u0 = &gaussinicial; /* Funcao de {x} que define o estado para {t=0}. */ //Funcao *u0 = &pulso; /* Funcao de {x} que define o estado para {t=0}. */ //Funcao *u0 = &seno; /* Funcao de {x} que define o estado para {t=0}. */ Funcao *u0 = &riemann; /* Funcao de {x} que define o estado para {t=0}. */ //Funcao *u0 = &riemann2; /* Funcao de {x} que define o estado para {t=0}. */ //Funcao *u0 = &riemann3; /* Funcao de {x} que define o estado para {t=0}. */ //Funcao *u0 = &bseno; /* Funcao de {x} que define o estado para {t=0}. */ Fluxo *flx = &adveccao; /* Funcao de {u} que define o fluxo continuo. ----- Adveccao */ //Fluxo *flx = &burger; /* Funcao de {u} que define o fluxo continuo. ----- Burger */ //Fluxo *flx = &diferente; /* Funcao de {u} que define o fluxo continuo. ----- Diferente */ //Fluxo *flx = &buckleyLeverett; /* Funcao de {u} que define o fluxo continuo. ----- Buckley-Leverett */ double eps = 0.1; /* Tolerancia para poda da arvore. */ bool_t podar; /* elimina ou nao os nos superfluos? */ bool_t haar; // analise usando wavelets de haar /* algoritmos de analise multiresolucao */ //aproxima_funcao(d, xmin, xmax, f, niv_tot, eps, tp, pac, integra, interpola_quad, podar, haar); //bool_t sim = TRUE; // despreza coeficientes irrelevantes //bool_t recs = TRUE; // reconstroi ? //amr( d, pac, niv_tot, xmin, xmax, 0, interpola_quad, eps, sim, haar, recs); //apaga_arvore(pac[kc].p); //DoEPSTests(OUT_PREFIX); //fprintf(stderr,"-- Tchau --\n"); //return EXIT_SUCCESS; //MakeTree(OUT_PREFIX, pac[kc].p, niv_tot); //DoMesh(OUT_PREFIX, pac[kc].p, 0); /* Desenha as tendas da base diadica */ /* DrawTentMin(OUT_PREFIX, pac, 2, 0, interpola_quad, xmin, xmax); DrawTentMax(OUT_PREFIX, pac, 2, 0, interpola_quad, xmin, xmax); */ /* Desenha um spline generico sobre uma malha (nos vertices o valor eh dado por {f} )*/ //splineExemplo(OUT_PREFIX, pac, d, 0, interpola_quad, xmin, xmax, f); /* com problema */ /* Determina menor dimensao {Dmin} do dominio: */ double Dmin = +INF; for (i = 0; i < d; i++) { double Dx = xmax[i] - xmin[i]; if (Dx < Dmin) { Dmin = Dx; } } //double c = 1.0; /* por enquanto, depois tem que mudar a forma de calcular o passo no tempo */ /* Determina o passo no tempo {Dt}: */ double T = 0.3; //pow((2.0*sqrt(3.0)),d-1)*Dmin/c; /* Tempo para uma volta completa. */ int tam1 = ipow(2,(niv_tot+d-1)/d); /* Numero de celulas por eixo (arred. p. cima). */ double Dx = Dmin/tam1; /* Tamanho minimo da celula. */ double cfl = 0.6; double Dt = cfl*Dx; /* Passo no tempo para atravessar meia celula. */ int N = T/Dt + 1; //ifloor(T/Dt + 0.5, 1); /* Numero de passos para volta completa. */ fprintf(stderr, "T = %.3f\n", T); fprintf(stderr, "Dmin = %.3f\n", Dmin); fprintf(stderr, "Dx = %.6f\n", Dx); fprintf(stderr, "Dt = %.6f\n", Dt); fprintf(stderr, "N = %d\n", N); /* gera arquivo analitic-solution.txt, com dados para plotar grafico da solucao analitica no tempo t = N*Dt */ //VNo pac[tm]; //solanalitica_advec( d, xmin, xmax, u0, niv_tot, N-1, Dt, tp, pac, integraSA, interpola); //Funcao *sol = &sol_burg_riem; //confira o t dessa funcao para ver se eh o mesmo la de baixo. //solanalitica_burg( d, xmin, xmax, sol, niv_tot, N-1, Dt, tp, pac, integraSA, interpola); //for(i=0;i1 ? i-1 : i; int pos = i!=1 ? kc - ipow(tp,k) : kc; pc[i].p = pac[pos].p; int dir; for(dir=0;dirflxsup[dir]; pc[i].fvi[dir] = pac[pos].p->flxinf[dir]; } } /* primeiro passo de Runge-Kutta 2 */ avancaTempoMeio(d, 0, pc, xmin, xmax, Dt, flx); /* aTM */ /* atualiza as folhas da arvore (manda fv[0] <--> fval ) */ atualiza_folhas(pac[kc].p); /* atualiza os nos internos da arvore */ atualiza_arvore(pac[kc].p); /* com aTM */ calcula_fluxosT( d, 0, pac, xmin, xmax, interpola, flx, op); // fluxo de roe //calcula_fluxos_upwind( d, 0, pac, xmin, xmax, interpola, flx, op); //calcula_fluxo_weno_v2( d, 0, pac, xmin, xmax, flx, interpola, ow, op); for(i=0;i<=d;i++) { int k = i>1 ? i-1 : i; int pos = i!=1 ? kc - ipow(tp,k) : kc; pc[i].p = pac[pos].p; int dir; for(dir=0;dirflxsup[dir]; pc[i].fvi[dir] = pac[pos].p->flxinf[dir]; } } /* segundo passo de Runge-Kutta */ avancaTempoUm( d, 0, pc, xmin, xmax, Dt, flx); /* aTU */ /* Remesh */ /* atualiza as folhas da arvore (manda fv[0] <--> fval ) */ atualiza_folhas(pac[kc].p); /* atualisar os nos internos da arvore */ atualiza_arvore(pac[kc].p); /* poda */ if(podar){poda( d, op, pac, niv_tot, xmin, xmax, 0, interpola, eps, podar, haar);} //grafica( d, n, N, PLOT_STEP, pac, interpola_quad, xmin, xmax, h1); // nao funciona, ainda if ((n <= 10) || (n == N-1) || (n % PLOT_STEP == 0)) { /* mede erro entre solucao numerica e analitica na norma L1 e grava ni arquivo err */ //double erro = 0.0; //erro_l1_analitica_numerica( d, 0, xmin, xmax, n*Dt, pac[kc].p, f, integra, &erro, c); //fprintf(err,"%f %f\n", n*Dt, erro); /* plot */ //fprintf(stderr,"aqui\n"); //char str[100]; // so para mostrar na tela //sprintf(str,"solucao.txt"); //FILE *risco = fopen(str, "w"); //escreve_em_arquivo( d, 0, risco, pac, xmin, xmax, interpola, 1, FALSE, op); //fclose(risco); // para que fique armazenado, caso eu precise //sprintf(str,"%s%08d%s%06f", "solucao-n-", n,"-eps-", eps); //FILE *cisco = fopen(str, "w"); //escreve_em_arquivo( d, 0, cisco, pac, xmin, xmax, interpola, 1, FALSE, op); //fclose(cisco); //int nf = 0; //conta_folhas(pac[kc].p, &nf); //fprintf(stderr, "plotando: passo = %d folhas = %d\n",n,nf); //fprintf(comp,"%f %f\n", n*Dt, 100.0-nf*100.0/pow(2,niv_tot)); //exportando( d, h1); //plotando(d,h1); //sleep(nf/100000 + 2); //MakeTree(OUT_PREFIX, pac[kc].p, niv_tot, n); //DoMesh(OUT_PREFIX, pac[kc].p, n); //DoMeshND( d, OUT_PREFIX, pac[kc].p, n, xmin, xmax, xmin, xmax); } } // so para mostrar na tela sprintf(str,"solucao.txt"); FILE *risco = fopen(str, "w"); escreve_em_arquivo( d, 0, risco, pac, xmin, xmax, interpola, 1, FALSE, op); fclose(risco); plotando(d,h1); gnuplot_close(h1) ; } double *read_vector(FILE *rd) { int n; assert(fscanf(rd, "%d", &n) == 1); double *v = notnull(malloc(n*sizeof(double)), "no mem"); int i; for (i = 0; i < n; i++) { assert(fscanf(rd, "%lg", &(v[i])) == 1); } return v; } /* void solucao_analitica(int d, bool_t op, bool_t ow, int N, int niv_tot, int tp, double eps, double Dt, double xmin[], double xmax[], VNo pac[], Funcao f, Fluxo flx, bool_t haar, bool_t podar) { auto double solanalitica(int d, int N, double Dt, double x[], Funcao f); double solanalitica(int d, int N, double Dt, double x[], Funcao f) { double xc = 0.0; // Supoe que dominio eh [-1,1]^d double dist = 0; double t = Dt*N; double a,b; int i; for (i = 0; i < d; i++) { double px = x[i]; double cx = xc + t; int lim = cx; if(lim%2==0){ a = lim - 1.0; b = lim + 1.0;} else{ a = lim; b = a + 2.0;} double n = -(b+a)/(b-a); double m = (1-n)/b; double d = m*px + n; double c = m*cx + n; // double dx = d - c; double dx = fabs(px + 2.0 - c) < fabs(px - c) ? fabs(px + 2.0 - c) : fabs(px - c); // double dx = px - c; dist += dx*dx; } // double r = 0.01; //Raio da gaussiana. // // double vf = 0.9*exp(-dist/r); // Gaussiana centrada em {xc,yc} //dist = dx*dx + dy*dy; //r = 0.01; //vf = 3.0*exp(-dist/r); // caracteristica // double r = 0.5, vf; if( dist< r*r) { vf = 1.0; } else { vf = 0.0; } return vf; } } */