Contrib:KeesWouters/Homard/lshape/loop

From CAELinuxWiki
Revision as of 11:05, 23 February 2010 by Keeswouters (Talk | contribs) (''Remarks on Python language'')

Jump to: navigation, search

Mesh refinement using Python loop facility

[under construction - just started 2010-02-22 ... ]

This contribution is based on the mesh refinement described here. Two mesh refinements based on three calculations are given there. Since the three calculations are basically the same, it is convenient to use the Python looping facility. So now we will perform four calculations and three mesh refinements. The iteration is controlled by the a Python for loop.

The geometry

The geometry and the mesh of the construction

The mesh refinement is based on Homard. As usual the geometry is quite simple and is defined in the link given above.

Kw lshape.jpg

Again, the mesh consists of coarse, tetrehedral elements to start with.

The load of the construction

The L shape is fixed in all directions at the bottom area Afix. The area at opposite end of L is denoted Apres. For simplicity, on this area a displacement of 0.1 mm is given in the y direction.

The general idea of the refinement

The general idea of the Homard refinement is to start with a rather course mesh and update the mesh according to a criterium. In this case we use the stress error estimate ERRE_ELEM_SIGM and its component ERREST. For more details on this error estimation see [....]. So to start with, a standard load case will be calculated and an error estimation on all the elements will be carried out. Again depending on a criterium the mesh will be adapted. In this example a certain percentage of the elements with the highest error estimates will be refined. A new calculation with the adapted mesh can take place. For this calculation all the models, loads and parameters need to be rebuild. So it is most suitable to define geometrical entities (GROUP_MA) in the mesh in stead of nodes.

To summarise:

  • initial some parameters
  • read initial mesh
  • define material properties
  • define number of refinement iterations (whether or not fixed)
  • for counter in [0,1,2,3]:
  • ...define model
  • ...apply material to model
  • ...apply load to model
  • ...perform calculation
  • ...determine element and node parameters
  • ...(write output data)
  • ...refinement of mesh MACR_ADAP_MAIL

The error estimation is determined in the CALC_ELEM command, by the option 'ERRE_ELEM_SIGM':

result...=CALC_ELEM(....,OPTION=(....,'ERRE_ELEM_SIGM',),);

The refinement command itself is as follows:

  ......
  print mesh
  print model
  counterp1 = counter+1;
  meshcp1=CO('mesh_%d' %counterp1)
  MACR_ADAP_MAIL(MAILLAGE_N=mesh[counter],
              MAILLAGE_NP1=meshcp1,
              ADAPTATION='RAFFINEMENT',
              RESULTAT_N=result[counter],
              INDICATEUR='ERRE_ELEM_SIGM',
              NOM_CMP_INDICA='ERREST',
              CRIT_RAFF_PE=0.20,
              QUALITE='OUI',
              CONNEXITE='OUI',
              TAILLE='OUI',);
  mesh[counter+1] = meshcp1;


The command takes the current mesh mesh[counter] as input MAILLAGE_N=curmesh and the output mesh is MAILLAGE_NP1=meshcp1. Again, the meshcp1 is not defined (in the Python sense) so we need to use the CO('..') operator on forehand:

  counterp1 = counter+1;
  meshcp1=CO('mesh_%d' %counterp1)

Further keywords are the ADAPTATION='RAFFINEMENT' together with CRIT_RAFF_PE=0.10. In this case the 0.10 or 10 % of the elements with the largest error estimate (based on stress error indicator INDICATEUR='ERRE_ELEM_SIGM', NOM_CMP_INDICA='ERREST') are refined. The other elements remain untouched. At the end we need to assign the next element of array mesh to the newly defined meshcp1: mesh[counter+1] = meshcp1. The if statement is needed because in the last iteration no refinement is required anymore.

Note: I mainly based this command file on the astest example zzzz121a.comm (see links below). In that case the statement immediately after macro command MACR_ADAP_MAIL mesh[counter+1] = meshcp1 is not included. For my examples it doesnot work without this.


Remarks on Python language

First note that 'test_%d',%3 will evaluate to 'test_3' in Python. Now suppose counter=1, counterp1=2 then meshcp1 evaluates to 'mesh_2' = CO('mesh_2'). The new name 'mesh_2' is defined. This corresponds to mesh[2]. To check this the print commands print model and print mesh have been added at the start of this block. The output of these commands are e.g:


print mesh,print model,.....:

[<maillage_sdaster(72a5fd0,'mesh_0                  ')>, <maillage_sdaster(56ed650,'mesh_1                  ')>, None , None]
[<modele_sdaster(72becd0,'model_0                 ')>, <modele_sdaster(56ed750,'model_1                 ')>, None , None]
[<char_meca(5af3110,'Load_0                  ')>, <char_meca(56fa6d0,'Load_1                  ')>, None , None]
[<cham_mater(5661fd0,'Amat_0                  ')>, <cham_mater(56eb290,'Amat_1                  ')>, None , None]
[<evol_elas(56e49d0,'result_0                ')>, <evol_elas(56ff690,'result_1                ')>, None , None]

Command control the Python for loop is controlled by indenting the commands by a fixed number of characters:

maxcount = 4;
for counter in range(0,maxcount):
   do_something();
   if (counter<maxcount-1):
      donotrefine();
   else:
      refine();
   #endif
#endfor

The range command yields:

maxcount=4;
xx = range(0,maxcount);xx

--> xx=[0,1,2,3]

The initialisation of the calculation

Here the initialisation commands that can be left out the for loop are described:

DEBUT();
# initialise counters
count = [0,1,2,3];
count0 = count[0];
# initialise model parameters
mesh=[None]*4
model=[None]*4
Amat=[None]*4
result=[None]*4
Load=[None]*4
#Define material properties
steel=DEFI_MATERIAU(ELAS=_F(E=2.1e5,NU=.28,),);
#Read MED mesh file
mesh[count0]=LIRE_MAILLAGE(UNITE=20,FORMAT='MED',NOM_MED='mesh0',);


In the array count all the loop numbers 0 to 3 are defined. This is used to control the for loop. The array parameters mesh, model, Amat, result and Load are initialised with maximum size according to the count array. Furthermore teh material properties are defined and the initial mesh is read.

The for loop construction

# start counter
for counter in count:
  model[counter]=AFFE_MODELE(MAILLAGE=mesh[counter],AFFE=_F(TOUT='OUI',
                         PHENOMENE='MECANIQUE',MODELISATION='3D',),);


  #Assign material to mesh
  Amat[counter]=AFFE_MATERIAU(MAILLAGE=mesh[counter],
                              AFFE=_F(TOUT='OUI',MATER=steel,),);
  #define boundary conditions and loads
  Load[counter]=AFFE_CHAR_MECA(MODELE=model[counter],
                    DDL_IMPO=(_F(GROUP_MA='Afix',DX=0.0,DY=0.0,DZ=0.0,),
                              _F(GROUP_MA='Apres',DX=0.0,DY=0.1,DZ=0.0,),),);
  result[counter]=MECA_STATIQUE(MODELE=model[counter],
                    CHAM_MATER=Amat[counter],
                    EXCIT=(_F(CHARGE=Load[counter],),),);
  result[counter]=CALC_ELEM(reuse =result[counter],
                MODELE=model[counter],
                RESULTAT=result[counter],
                TOUT='OUI',
                TYPE_OPTION='TOUTES',
                OPTION=('EQUI_ELNO_SIGM','SIEF_ELNO_ELGA','ERRE_ELEM_SIGM',),);
  result[counter]=CALC_NO(reuse =result[counter],
              RESULTAT=result[counter],
              OPTION=('EQUI_NOEU_SIGM',),);


  unitnumber = 80
  IMPR_RESU(FORMAT='MED',
         UNITE=unitnumber,
         RESU=_F(MAILLAGE=mesh[counter],RESULTAT=result[counter],NOM_CHAM=('DEPL',),),);


  ##========================##
  ## define mesh refinement ##
  ##========================##
  if (counter<count[len(count)-1]):
     print count, len(count), count[len(count)-1], counter
     print mesh
     print model
     
     counterp1 = counter+1;
     meshcp1=CO('mesh_%d' %counterp1)
     MACR_ADAP_MAIL(MAILLAGE_N=mesh[counter],
              MAILLAGE_NP1=meshcp1,
              ADAPTATION='RAFFINEMENT',
              RESULTAT_N=result[counter],
              INDICATEUR='ERRE_ELEM_SIGM',
              NOM_CMP_INDICA='ERREST',
              CRIT_RAFF_PE=0.10,
              QUALITE='OUI',
              CONNEXITE='OUI',
              TAILLE='OUI',);
     mesh[counter+1] = meshcp1;
     #endif
  #end for loop

And close the calculations:

FIN(FORMAT_HDF='OUI',);


All the results are now written to a single file on unit 80. In Salome's object browser the results are available after 'file' --> 'import'--> '<resultfile>.med' under mesh_0, mesh_1, mesh_2 and mesh_2. Each mesh contains a DEPL under fields.

The results of the refinement

The numbers of nodes and quadratic elements (tetrahedrons) of the meshes:

                        10%          90%        new    change
nodes	elements     changed	unchanged   elements	factor
4224	    2064	 206	     1858		
8796	    4958	 496	     4462	3100	15 (= 3100/ 206)
20043	   12029	1203	    10826	7567	15 (= 7567/ 496)
45066	   28347	2835	    25512      17521	15 (=17521/1203)


So, from a single tetrahedron that is refined, 15 tetrahedrons are generated for this mesh.

In the graph below, the original mesh (top left) and the two successive refinements based on the discussed criteria are depicted (bottom right last iteration).

Kw refinement 4.jpg

The picture below shows the stress error estimation 'ERREST'. The first refinement is based on this field: mesh0 --> mesh1.

The ASTK input files

The picture below shows the input and output files defined in ASTK.

Download files

Media:kw_mesh_refinement012.zip

This zip contains the following files

  • python geometry and mesh files (load in Salome by File --> Load script (cntrl T)) and right select refresh (F5) in the object browser). Export the med file in the mesh module under mesh0.med for further processing by Code-Aster, controlled by ASTK.
  • command files for Code-Aster
  • astk file for file control by ASTK
  • export file, generated by ASTK.

The result file resx0.med can be viewed in the post processor module of Salome by File --> Import --> resix.med or cntrl I in the object browser. Importing it into the mesh module can be useful to check e.g. the number of elements.

Links

More information about the mesh refinement by Homard can be find here:
pdf file: http://www.code-aster.org/V2/doc/default/man_u/u7/u7.03.01.pdf
Homard website: http://www.code-aster.org/outils/homard

Not really links, but nice to study are the examples
zzzz121a.comm, zzzz121b.comm, zzzz121c.comm, zzzz121d.comm and zzzz121e.comm
in the astest directory [$ASTER_ROOT]/STA[$VERSION]/astest/.....,
e.g in my case: /cae/aster101/STA10.1/astest/zzzz121a.comm

That's it for now.
Kees