Ejemplo n.º 1
0
Archivo: mesh.c Proyecto: flaeddi/ulmsp
void refine_uniform(prealmatrix   coordinates,      /* in / out */
                    pindexmatrix  elements,         /* in / out */
                    prealvector   material,         /* in / out */
                    pindexmatrix  elements2edges,   /* in / out */
                    pindexmatrix  edgeno,           /* out      */
                    pindexmatrix *bdrylist,         /* in / out */
                    pindexvector *bdry2edgeslist,   /* in / out */
                    const int     nBdry){           /* in       */
    /* Allocate local variables */
    int iBdry;
    index *B, *B2e, *nB, *nB2e;
    index nEdges, nTria, nCoord;
    index *E, *E2e, *nE, *nE2e, *nEno;
    real *M, *nM;
    real *C, *nC;
    index i, i0, i1, k, p;
    int isucc[3] = {1,2,0}, iprae[3] = {2,0,1};
    prealmatrix new_coordinates;
    prealvector new_material;
    pindexmatrix new_elements, new_elements2edges, new_bdrylist, new_edgeno;
    pindexvector new_bdry2edgeslist;

    /* Check proper input */
    assert(coordinates);  assert(elements);
    assert(material);     assert(elements2edges);
    assert(edgeno);       assert(bdrylist);
    assert(nBdry);

    /* Set mesh sizes */
    nCoord = coordinates->cols;    /* Number of coordinates */
    nTria  = elements->cols;       /* Number of triangles */

    E2e = elements2edges->vals;
    nEdges = 0;                    /* Number of edges */
    for (i=0 ; i<3*(elements2edges->cols); ++i)
       if ( E2e[i]> nEdges) nEdges = E2e[i];
    nEdges+=1-INDEX_BASE;

    /* Allocate storage for refined mesh */
    new_coordinates = new_realmatrix(2,nCoord+nEdges);
    new_elements = new_indexmatrix(3,4*nTria);
    new_material = new_realvector(4*nTria);
    new_elements2edges = new_indexmatrix(3,4*nTria);
    new_edgeno = new_indexmatrix(2,nEdges);

    /* Declare local variables for convinience */
    C = coordinates->vals; nC = new_coordinates->vals;
    E = elements->vals; nE = new_elements->vals;
    M = material->vals; nM = new_material->vals;
    nE2e = new_elements2edges->vals;
    nEno = new_edgeno->vals;

    /* Get endpoints for each edge, i.e. compute edgeno */
    for (i=0 ; i<nTria ; ++i){
      for (k=0 ; k<3 ; ++k){
        p=3*i+k;
        nEno[2*(E2e[p]-INDEX_BASE)  ] = E[p];
        nEno[2*(E2e[p]-INDEX_BASE)+1] = E[3*i+isucc[k]];
      }
    }

    /* Copy old coordinates */
    for (i=0 ; i<2*nCoord ; i++) nC[i] = C[i];
    /* Compute new coordinates */
    for (i=0 ; i<nEdges ; i++){
      i0 = nEno[2*i]  -INDEX_BASE;
      i1 = nEno[2*i+1]-INDEX_BASE;
      nC[2*nCoord+2*i  ] = 0.5*(C[2*i0  ] + C[2*i1  ]);
      nC[2*nCoord+2*i+1] = 0.5*(C[2*i0+1] + C[2*i1+1]);
    }


    /* Loop over all elements */
    for (i=0 ; i<nTria ; i++){
      for (k=0 ; k<3 ; k++){
        nE[12*i+3*k+0] = E[3*i+k];
        nE[12*i+3*k+1] = nCoord + E2e[3*i+k];
        nE[12*i+3*k+2] = nCoord + E2e[3*i+iprae[k]];

        nE2e[12*i+3*k+0] = 2*E2e[3*i+k]-INDEX_BASE+ (E[3*i+k]>E[3*i+isucc[k]]);
        nE2e[12*i+3*k+1] = 2*nEdges+3*i+k+INDEX_BASE;
        nE2e[12*i+3*k+2] = 2*E2e[3*i+iprae[k]]-INDEX_BASE+ (E[3*i+k]>E[3*i+iprae[k]]);

        nM[4*i+k] = M[i];
      }
      nE[12*i+ 9] = nCoord + E2e[3*i  ];
      nE[12*i+10] = nCoord + E2e[3*i+1];
      nE[12*i+11] = nCoord + E2e[3*i+2];

      nE2e[12*i+ 9] = 2*nEdges+3*i+1+INDEX_BASE;
      nE2e[12*i+10] = 2*nEdges+3*i+2+INDEX_BASE;
      nE2e[12*i+11] = 2*nEdges+3*i+0+INDEX_BASE;

      nM[4*i+3] = M[i];
    }

    /* Refine boundary */
    new_bdrylist = new_indexmatrix(0,0);
    new_bdry2edgeslist = new_indexvector(0);
    /* Loop over all boundary pieces */
    for (iBdry=0 ; iBdry<nBdry ; iBdry++){
      resize_indexmatrix(new_bdrylist,2,2*bdrylist[iBdry]->cols);
      resize_indexvector(new_bdry2edgeslist,2*bdrylist[iBdry]->cols);
      B = bdrylist[iBdry]->vals; B2e = bdry2edgeslist[iBdry]->vals;
      nB = new_bdrylist->vals; nB2e = new_bdry2edgeslist->vals;
      for (i=0 ; i<bdrylist[iBdry]->cols ; i++){
        /* Refine bdrylist[iBdry]*/
        nB[4*i  ] = B[2*i];
        nB[4*i+1] = nCoord+B2e[i];
        nB[4*i+2] = nCoord+B2e[i];
        nB[4*i+3] = B[2*i+1];

        /* Refine bdry2edgeslist[iBdry]*/
        nB2e[2*i  ] = 2*B2e[i  ] + (B[2*i  ] > B[2*i+1]) - INDEX_BASE;
        nB2e[2*i+1] = 2*B2e[i  ] + (B[2*i+1] > B[2*i  ]) - INDEX_BASE;
      }
      swap_indexmatrix(bdrylist[iBdry], new_bdrylist);
      swap_indexvector(bdry2edgeslist[iBdry], new_bdry2edgeslist);
    }

    swap_realmatrix(coordinates, new_coordinates);
    swap_realvector(material, new_material);
    swap_indexmatrix(edgeno, new_edgeno);
    swap_indexmatrix(elements, new_elements);
    swap_indexmatrix(elements2edges, new_elements2edges);

    del_realmatrix(new_coordinates);
    del_realvector(new_material);
    del_indexmatrix(new_edgeno);
    del_indexmatrix(new_elements);
    del_indexmatrix(new_elements2edges);

    del_indexmatrix(new_bdrylist);
    del_indexvector(new_bdry2edgeslist);
}
Ejemplo n.º 2
0
int
main(int argc, char **argv)
{
    int nItCG, nLevel = 2;
    long TIME[9];
    int nBdry = 2;

    pcoo S = new_coo(1,1,1);
    pcrs A = new_crs(1,1,1);
    pindexmatrix edgeno = new_indexmatrix(0,0);

    pindexmatrix   *s2p = NULL;
    pindexvector   *fixedNodes = NULL;
    pindexvector material;
    prealmatrix coordinates;
    pindexmatrix elements;
    pindexmatrix elements2edges;

    pindexvector bdrytyp = new_indexvector(2);
    pindexmatrix bdrylist[2];
    pindexvector bdry2edgeslist[2];

    prealvector rhs;
    prealvector sol;

    /* Number of refinements */ 
    if (argc>1){
      if (atoi(argv[1]) < 12) nLevel = atoi(argv[1]);
    }
    /* Load geometry */
    material
            = load_indexvector("./Tests/Example1/material.dat");
    coordinates
            = load_realmatrix("./Tests/Example1/coordinates.dat",(index)2,1);
    elements
            = load_indexmatrix("./Tests/Example1/elements.dat",3,1);
    elements2edges
            = load_indexmatrix("./Tests/Example1/elements2edges.dat",3,1);
    bdrytyp->vals[0] = 0;
    bdrytyp->vals[1] = 1;
    bdrylist[0] = load_indexmatrix("./Tests/Example1/Dirichlet.dat",2,1);
    bdrylist[1] = load_indexmatrix("./Tests/Example1/Neumann.dat",2,1);
    bdry2edgeslist[0] = load_indexvector("./Tests/Example1/Dirichlet2edges.dat");
    bdry2edgeslist[1] = load_indexvector("./Tests/Example1/Neumann2edges.dat");


    /* Show geometry */
    printf("====================\n");
    printf("coordinates:\n");
    printf("====================\n");
    print_realmatrix(coordinates);
    printf("====================\n");
    printf("elements:\n");
    printf("====================\n");
    print_indexmatrix(elements);
    printf("====================\n");
    printf("elements2edges:\n");
    printf("====================\n");
    print_indexmatrix(elements2edges);
    printf("====================\n");
    printf("material:\n");
    printf("====================\n");
    print_indexvector(material);
    printf("====================\n");
    printf("bdrylist:\n");
    printf("====================\n");
    print_indexmatrix(bdrylist[0]);
    printf("--------------------\n");
    print_indexmatrix(bdrylist[1]);
    printf("====================\n");
    printf("bdry2edgeslist:\n");
    printf("====================\n");
    print_indexvector(bdry2edgeslist[0]);
    printf("--------------------\n");
    print_indexvector(bdry2edgeslist[1]);
    printf("====================\n");

    TIME[0] = clock();

    /* Refine mesh uniformly */
    create_hierarchy(nLevel,            /* in       */
                     coordinates,       /* in / out */
                     elements,          /* in / out */
                     material,          /* in / out */
                     elements2edges,    /* in       */
                     s2p,               /* out      */
                     nBdry,             /* in       */
                     bdrytyp,           /* in       */
                     bdrylist,          /* in / out */
                     bdry2edgeslist,          /* in / out */
                     NULL,              /* in / out */
                     fixedNodes);            /* in / out */

    TIME[1] = clock();

    write_realmatrix("./Tests/Example1/coordinates_fine.dat",coordinates,1);
    write_indexmatrix("./Tests/Example1/elements_fine.dat",elements,1);
    write_indexmatrix("./Tests/Example1/elements2edges_fine.dat",elements,1);
    write_indexvector("./Tests/Example1/material_fine.dat",material);
    write_indexmatrix("./Tests/Example1/Dirichlet_fine.dat",bdrylist[0],1);
    write_indexmatrix("./Tests/Example1/Neumann_fine.dat",bdrylist[1],1);
    write_indexvector("./Tests/Example1/Dirichlet2edges_fine.dat",bdry2edgeslist[0]);
    write_indexvector("./Tests/Example1/Neumann2edges_fine.dat",bdry2edgeslist[1]);

    rhs = new_realvector(coordinates->cols);
    sol = new_realvector(coordinates->cols);

    TIME[2] = clock();

    buildStiffness(coordinates, elements, S);

    TIME[3] = clock();

    init_coo2crs(A, S);

    TIME[4] = clock();

    buildRhs(coordinates, elements, VolForce, rhs);
    copy_realvector(sol, rhs);
    setDirichletData2Rhs(coordinates, fixedNodes[0], uD, sol);

    TIME[5] = clock();

    nItCG = cgcrs_constrains(A,sol,rhs, fixedNodes[0],1e-6,coordinates->cols);
    printf("No. iterations %i\n", nItCG);

    TIME[6] = clock();

    write_realvector("./Tests/Example1/sol_fine.dat",sol);

    TIME[7] = clock();

    printf("---------------------\n");
    printf("Time for refinement       = %i ms\n", ELAPSED(TIME[0],TIME[1]));
    printf("Time for saving ref. mesh = %i ms\n", ELAPSED(TIME[1],TIME[2]));
    printf("Time for assembling       = %i ms\n", ELAPSED(TIME[2],TIME[3]));
    printf("Time for COO -> CRS       = %i ms\n", ELAPSED(TIME[3],TIME[4]));
    printf("Time for RHS              = %i ms\n", ELAPSED(TIME[4],TIME[5]));
    printf("Time for solving          = %i ms\n", ELAPSED(TIME[5],TIME[6]));
    printf("Time store solution       = %i ms\n\n", ELAPSED(TIME[6],TIME[7]));
    printf("Degrees of elements / freedom %lu / %lu\n", elements->cols, coordinates->cols);

    printf("---------------------\n");

    del_coo(S);
    del_crs(A);
    del_realvector(rhs); 
    del_realvector(sol);
    del_indexmatrix(edgeno);


    del_realmatrix(coordinates);
    del_indexmatrix(elements);
    del_indexmatrix(elements2edges);
    del_indexvector(material);
 
    return 0;
}