SPModel: libSPModel/src/SurfaceRegularMesh.c Source File
VPAC - Computational Software Development
Main | SPModel | StGermain FrameWork |
Main Page | Alphabetical List | Class List | Directories | File List | Class Members | File Members

SurfaceRegularMesh.c

Go to the documentation of this file.
00001 /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
00002 **
00003 ** Copyright (C), 2004, Victorian Partnership for Advanced Computing (VPAC) Ltd, 110 Victoria Street, Melbourne, 3053, Australia.
00004 **
00005 ** Authors:
00006 **  Ogar R. Widjaja, Computational Scientist, VPAC.
00007 **  Raquibul Hassan, Software Engineer, VPAC. (raq@vpac.org)
00008 **  Keith Hsuan, Computational Scientist, VPAC (keith@vpac.org)
00009 **  William F. Appelbe, Director, VPAC. (bill@vpac.org)
00010 **  Stevan M. Quenette, Senior Software Engineer, VPAC. (steve@vpac.org)
00011 **  Patrick D. Sunter, Software Engineer, VPAC. (patrick@vpac.org)
00012 **
00013 ** This file may be distributed under the terms of the VPAC Public License
00014 ** as defined by VPAC of Australia and appearing in the file
00015 ** LICENSE.VPL included in the packaging of this file.
00016 **
00017 ** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
00018 ** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
00019 **
00020 */
00030 #include <mpi.h>
00031 #include <StGermain/StGermain.h>
00032 #include <Cascade/cascade.h>
00033 
00034 #include "types.h"
00035 
00036 #include <stdio.h>
00037 #include <stdlib.h>
00038 #include <string.h>
00039 #include <assert.h>
00040 #include <math.h>
00041 #include "Catchment.h"
00042 #include "SurfaceMesh.h"
00043 #include "Context.h"
00044 #include "SurfaceRegularMesh.h"
00045 #include "_Interpolator.h"
00046 #include "LinearInterpolator.h"
00047 #include "SplineInterpolator.h"
00048 
00049 /* Textual name of this class */
00050 const Type SurfaceRegularMesh_Type = "SurfaceRegularMesh";
00051 
00052 SurfaceRegularMesh *SurfaceRegularMesh_DefaultNew( Name name )
00053 {
00054     return _SurfaceRegularMesh_New( sizeof( SurfaceRegularMesh ),
00055                                 SurfaceRegularMesh_Type,
00056                                 _SurfaceRegularMesh_Delete,
00057                                 _SurfaceRegularMesh_Print,
00058                                 NULL,
00059                                 (void*)SurfaceRegularMesh_DefaultNew,
00060                                 _SurfaceRegularMesh_Construct,
00061                                 _SurfaceRegularMesh_Build,
00062                                 _SurfaceRegularMesh_Initialise,
00063                                 _SurfaceRegularMesh_Execute,
00064                                 _SurfaceRegularMesh_Destroy,
00065                                 name,
00066                                 False,
00067                                 NULL,
00068                                 NULL );
00069     
00070 }
00071 
00072 SurfaceRegularMesh *SurfaceRegularMesh_New( Name name, Dictionary *dictionary,
00073                                             SurfaceMesh *mesh )
00074 {
00075     return _SurfaceRegularMesh_New( sizeof( SurfaceRegularMesh ),
00076                                 SurfaceRegularMesh_Type,
00077                                 _SurfaceRegularMesh_Delete,
00078                                 _SurfaceRegularMesh_Print,
00079                                 NULL,
00080                                 (void*)SurfaceRegularMesh_DefaultNew,
00081                                 _SurfaceRegularMesh_Construct,
00082                                 _SurfaceRegularMesh_Build,
00083                                 _SurfaceRegularMesh_Initialise,
00084                                 _SurfaceRegularMesh_Execute,
00085                                 _SurfaceRegularMesh_Destroy,
00086                                 name,
00087                                 True,
00088                                 dictionary,
00089                                 mesh );
00090     
00091 }
00092 
00093 SurfaceRegularMesh                  *_SurfaceRegularMesh_New( SizeT                         _sizeOfSelf,
00094                                     Type                            type,
00095                                     Stg_Class_DeleteFunction*               _delete,
00096                                     Stg_Class_PrintFunction*                _print,
00097                                     Stg_Class_CopyFunction*             _copy, 
00098                                     Stg_Component_DefaultConstructorFunction*   _defaultConstructor,
00099                                     Stg_Component_ConstructFunction*            _construct,
00100                                     Stg_Component_BuildFunction*        _build,
00101                                     Stg_Component_InitialiseFunction*       _initialise,
00102                                     Stg_Component_ExecuteFunction*      _execute,
00103                                     Stg_Component_DestroyFunction*      _destroy,
00104                                     Name                            name,
00105                                     Bool                            initFlag,
00106                                     Dictionary                      *dictionary,
00107                                     SurfaceMesh                     *mesh )
00108 {
00109     SurfaceRegularMesh* self;
00110     
00111     /* Allocate memory */
00112     assert( _sizeOfSelf >= sizeof(SurfaceRegularMesh) );
00113     self = (SurfaceRegularMesh*)_Stg_Component_New( _sizeOfSelf, type, _delete, _print, _copy, _defaultConstructor, _construct, _build, 
00114             _initialise, _execute, _destroy, name, NON_GLOBAL );
00115 
00116     assert( dictionary );
00117     assert( mesh );
00118     
00119     self->dictionary = dictionary;
00120     self->mesh = mesh;
00121     
00122     if( initFlag ){
00123         _SurfaceRegularMesh_Init( self );
00124     }
00125 
00126     return self;
00127 }
00128 
00129 void _SurfaceRegularMesh_Init( SurfaceRegularMesh *self )
00130 {
00131     Dictionary *meshDict;
00132     
00133     assert( self );
00134 
00135     meshDict = Dictionary_Entry_Value_AsDictionary( Dictionary_Get( self->dictionary, "mesh" ) ); 
00136     
00137     self->nx = Dictionary_GetFloat_WithDefault( meshDict, "rnx", 64 );
00138     self->ny =Dictionary_GetFloat_WithDefault( meshDict, "rnx", 64 );
00139     
00140     Journal_Firewall( (self->nx > 0), Journal_Register( Error_Type, "errorStream" ), "0 nodes in x direction..!\n" );
00141     Journal_Firewall( (self->ny > 0), Journal_Register( Error_Type, "errorStream" ), "0 nodes in y direction..!\n" );
00142 }
00143 
00144 void _SurfaceRegularMesh_Print( void *surfaceRegularMesh, Stream *stream )
00145 {
00146     SurfaceRegularMesh *self = (SurfaceRegularMesh*) surfaceRegularMesh;
00147 
00148     assert( self );
00149     assert( stream );
00150 
00151     /* print parent */
00152     _Stg_Component_Print( (void*) self, stream );
00153 
00154     /* general info */
00155     Journal_Printf( stream, "SurfaceRegularMesh (ptr): (%p)\n", self );
00156 
00157     /* Virtual Info */
00158 
00159     /* SurfaceRegularMesh Info */
00160     
00161     Journal_Printf( stream, "Max number of nodes in x direction %d\n", self->nx );
00162     Journal_Printf( stream, "Max number of nodes in y direction %d\n", self->ny );
00163     
00164 }
00165 
00166 void _SurfaceRegularMesh_Delete( void *surfaceRegularMesh )
00167 {
00168     SurfaceRegularMesh *self = (SurfaceRegularMesh*)surfaceRegularMesh;
00169 
00170     assert( self );
00171 
00172     free( self->regularNodes[0] );
00173     free( self->regularNodes );
00174 
00175     free( self->dataArray[0] );
00176     free( self->dataArray );
00177     
00178     _Stg_Component_Delete( self );
00179 }
00180 
00181 void _SurfaceRegularMesh_Construct( void *surfaceRegularMesh, Stg_ComponentFactory *cf )
00182 {
00183     
00184 }
00185 
00186 void _SurfaceRegularMesh_Build( void *surfaceRegularMesh, void *data )
00187 {
00188     SurfaceRegularMesh *self = (SurfaceRegularMesh*) surfaceRegularMesh;
00189     int i = 0, j = 0;
00190     float dx, dy;
00191 
00192     assert( self );
00193     
00194     self->regularNodes = (RegularNode **) malloc( sizeof( RegularNode* ) *
00195     self->nx );
00196     memset( self->regularNodes, 0, sizeof( RegularNode* ) * self->nx );
00197     self->regularNodes[0] = malloc( sizeof( RegularNode ) * self->nx * self->ny );
00198     for( i=0; i<self->nx; i++ ){
00199         self->regularNodes[i] = self->regularNodes[0] + i * self->nx;
00200     }
00201 
00202     self->dataArray = (float**)malloc( sizeof(float*) * self->nx );
00203     self->dataArray[0] = (float*)malloc( sizeof(float) * self->nx * self->ny );
00204     for( i=0; i<self->nx; i++ ){
00205         self->dataArray[i] = self->dataArray[0] + i*self->nx;
00206     }
00207     
00208     dx = self->mesh->sideX / (self->nx - 1);
00209     dy = self->mesh->sideY / (self->ny - 1);
00210     for( i=0; i<self->nx; i++ ){
00211         for( j=0; j<self->ny; j++ ){
00212             self->regularNodes[i][j].id = i*self->nx + j + 1;
00213             self->regularNodes[i][j].x = dx * i;
00214             self->regularNodes[i][j].y = dy * j;
00215         }   
00216     }
00217 }
00218 
00219 void _SurfaceRegularMesh_Initialise( void *surfaceRegularMesh, void *data )
00220 {
00221 
00222 }
00223 
00224 void _SurfaceRegularMesh_Execute( void *surfaceRegularMesh, void *data )
00225 {
00226     
00227 }
00228 
00229 void _SurfaceRegularMesh_Destroy( void *surfaceRegularMesh, void *data )
00230 {
00231     
00232 }
00233 
00234 void SurfaceRegularMesh_BroadcastData( SurfaceRegularMesh *regularMesh )
00235 {
00236     assert( regularMesh );
00237 
00238     MPI_Bcast ( regularMesh->dataArray[0], regularMesh->nx*regularMesh->ny, MPI_FLOAT, MASTER_PROC, MPI_COMM_WORLD );
00239 }
00240 
00241 void SurfaceRegularMesh_GatherData( SurfaceRegularMesh *regularMesh, _Interpolator *interpolator )
00242 {
00243     typedef struct package_t{
00244         int i;
00245         int j;
00246         float value;
00247     }package;
00248     
00249     int i = 0, j = 0, k = 0;
00250     MPI_Status status;
00251     int count = 0;
00252     
00253     SurfaceMesh *mesh = NULL;
00254     package p;
00255 
00256     assert( regularMesh );
00257     assert( interpolator );
00258 
00259     mesh = regularMesh->mesh;
00260     
00261     if( mesh->rank == MASTER_PROC ){
00262 
00263         for( i=0; i<regularMesh->nx; i++ ){
00264             for( j=0; j<regularMesh->ny; j++ ){
00265 
00266                 for( k=0; k<mesh->numProcs; k++ ){
00267                     if( k == MASTER_PROC ){
00268                         continue;
00269                     }
00270                     
00271                     if( interpolator->mappingTable[i][j][k] ){
00272                         MPI_Recv( &p, sizeof(package), MPI_BYTE, k, FLEXURE_SEND_RECV_TAG,
00273                                 MPI_COMM_WORLD, &status );
00274                         
00275                         regularMesh->dataArray[p.i][p.j] += p.value;
00276                         assert( p.i == i );
00277                         assert( p.j == j );
00278                     }
00279                 }
00280                 
00281                 count = 0;;
00282                 for( k=0; k<mesh->numProcs; k++ ){
00283                     if( interpolator->mappingTable[i][j][k] ){
00284                         count++;
00285                     }
00286                 }
00287                 
00288                 if( count ){
00289                     regularMesh->dataArray[i][j] /= (double)(count);
00290                 }
00291             }
00292         }
00293     }
00294     else{
00295         for( i=0; i<regularMesh->nx; i++ ){
00296             for( j=0; j<regularMesh->ny; j++ ){
00297                 if( interpolator->nodesForGridPoint[i*regularMesh->nx+j]->nodeCount ){
00298                     p.i = i;
00299                     p.j = j;
00300                     p.value = regularMesh->dataArray[i][j];
00301                     MPI_Send( &p, sizeof( package ), MPI_BYTE, MASTER_PROC, FLEXURE_SEND_RECV_TAG,
00302                            MPI_COMM_WORLD );
00303                 }
00304             }
00305         }
00306     }
00307 }
00308