void _ElementCellLayout_Init( ElementCellLayout* self, void* mesh ) { /* General and Virtual info should already be set */ /* ElementCellInfo info */ self->mesh = (Mesh*)mesh; self->incArray = IArray_New(); }
void _ForceVector_Init( void* forceVector, Dimension_Index dim, EntryPoint_Register* entryPoint_Register ) { ForceVector* self = (ForceVector*) forceVector; /* ForceVector info */ self->dim = dim; self->entryPoint_Register = entryPoint_Register; /* Create Stream */ self->debug = Stream_RegisterChild( StgFEM_SLE_SystemSetup_Debug, self->type ); /* Create Entry Point for assembleForceVector */ Stg_asprintf( &self->_assembleForceVectorEPName, "%s-%s", self->name, ForceVector_assembleForceVectorStr ); self->assembleForceVector = FeEntryPoint_New( self->_assembleForceVectorEPName, FeEntryPoint_AssembleForceVector_CastType ); EntryPoint_Register_Add( self->entryPoint_Register, self->assembleForceVector ); /* Add default hook to assembleForceVector entry point */ EP_ReplaceAll( self->assembleForceVector, ForceVector_GlobalAssembly_General ); self->forceTermList = Stg_ObjectList_New(); self->bcAsm = Assembler_New(); self->inc = IArray_New(); self->nModifyCBs = 0; self->modifyCBs = NULL; }
void IArraySuite_Setup( IArraySuiteData* data ) { Index idx; data->iArray = IArray_New(); for( idx = 0; idx < NUM_ITEMS; idx++ ) { data->arrayData[idx] = idx; } }
void _Mesh_Algorithms_Init( Mesh_Algorithms* self, AbstractContext* context ) { self->context = context; self->nearestVertex = NULL; self->search = NULL; self->mesh = NULL; self->tree = NULL; MPI_Comm_rank( MPI_COMM_WORLD, &self->rank ); self->incArray = IArray_New(); }
void _GALEDivergenceForce_AssembleElement( void* forceTerm, ForceVector* forceVector, Element_LocalIndex lElement_I, double* elForceVec ) { GALEDivergenceForce* self=(GALEDivergenceForce*) forceTerm; FeMesh* mesh=forceVector->feVariable->feMesh; Node_ElementLocalIndex eNode_I; Element_NodeIndex elementNodeCount; Node_DomainIndex *elementNodes=NULL; double xi[3], force, factor; ElementType* geometryElementType; IArray *incidence; xi[0]=0; xi[1]=0; xi[2]=0; geometryElementType=FeMesh_GetElementType(self->geometryMesh,lElement_I); factor=ElementType_JacobianDeterminant( geometryElementType, self->geometryMesh, lElement_I, xi, forceVector->dim ); incidence=IArray_New(); Mesh_GetIncidence(mesh, Mesh_GetDimSize(mesh), lElement_I, MT_VERTEX,incidence); elementNodeCount=IArray_GetSize(incidence); elementNodes=IArray_GetPtr(incidence); for( eNode_I = 0 ; eNode_I < elementNodeCount; eNode_I++ ) { if(Stg_Shape_IsCoordInside(self->domainShape, Mesh_GetVertex(mesh,elementNodes[eNode_I]))) { switch(self->force.type) { case GALEStressBC_Double: force=self->force.DoubleValue; break; case GALEStressBC_ConditionFunction: /* We use a variable number of zero "0", because we don't use the variable number and that one is always going to exist. */ ConditionFunction_Apply (condFunc_Register->_cf[self->force.CFIndex], elementNodes[eNode_I],0,self->context,&force); break; } elForceVec[ eNode_I] += force*factor; } } Stg_Class_Delete(incidence); }
void TrilinearElementTypeSuite_TestShape( TrilinearElementTypeSuiteData* data ) { FeMesh* mesh = NULL; int nEls, nVerts, nDims; const int *verts; double* vert = NULL; double lCrd[3] = { 0.0, 0.0, 0.0 }; double basis[8] = { 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 }; IArray* inc; int e_i, v_i, v_j; mesh = buildMesh(); pcu_check_true( mesh ); Stg_Component_Initialise( mesh, data, True ); nDims = Mesh_GetDimSize( mesh ); nEls = Mesh_GetDomainSize( mesh, nDims ); inc = IArray_New(); for( e_i = 0; e_i < nEls; e_i++ ) { Mesh_GetIncidence( mesh, nDims, e_i, 0, inc ); nVerts = IArray_GetSize( inc ); verts = IArray_GetPtr( inc ); for( v_i = 0; v_i < nVerts; v_i++ ) { vert = Mesh_GetVertex( mesh, verts[v_i] ); FeMesh_CoordGlobalToLocal( mesh, e_i, vert, lCrd ); FeMesh_EvalBasis( mesh, e_i, lCrd, basis ); for( v_j = 0; v_j < nVerts; v_j++ ) { if( (v_i == v_j && !Num_Approx( basis[v_j], 1.0 )) || (v_i != v_j && !Num_Approx( basis[v_j], 0.0 )) ) { break; } } if( v_j < nVerts ) break; } if( v_i < nVerts ) break; } pcu_check_true( e_i == nEls ); Stg_Class_Delete( inc ); _Stg_Component_Delete( mesh ); }
void ForceVector_PrintElementForceVector( ForceVector* self, Element_LocalIndex element_lI, Dof_EquationNumber** elementLM, double* elForceVecToAdd ) { DofLayout* dofLayout = self->feVariable->dofLayout; FeMesh* feMesh = self->feVariable->feMesh; unsigned nInc, *inc; Dof_Index dofsPerNode; Node_LocalIndex nodesThisEl; Node_LocalIndex node_I; Dof_Index dof_I; Index vec_I; IArray* incArray; incArray = IArray_New(); FeMesh_GetElementNodes( feMesh, element_lI, incArray ); nInc = IArray_GetSize( incArray ); inc = IArray_GetPtr( incArray ); dofsPerNode = dofLayout->dofCounts[inc[0]]; nodesThisEl = nInc; for ( node_I=0; node_I < nodesThisEl; node_I++ ) { for ( dof_I = 0; dof_I < dofsPerNode; dof_I++ ) { vec_I = node_I * dofsPerNode + dof_I; Journal_DPrintf( self->debug, "Entry[%d][%d] (LM (%4d)) = %.3f\n", node_I, dof_I, elementLM[node_I][dof_I], elForceVecToAdd[vec_I] ); } } Stg_Class_Delete( incArray ); }
void lecode_tools_Isostasy_AverageSurfaces(lecode_tools_Isostasy *self, double** _avg_sep, double** _avg_height) { FeMesh *mesh; Grid *grid, *elGrid; double *local_height, *global_height; double *local_top_vy, *global_top_vy; double *local_bot_vy, *global_bot_vy; int *local_top_cnt, *global_top_cnt; int *local_bot_cnt, *global_bot_cnt; int param[3], elParam[3], num_nodes, n; double vel[3]; IArray *inc; int nDims, arrayPos, arraySize; int ii, jj; mesh = self->mesh; nDims = Mesh_GetDimSize( mesh ); grid = *Mesh_GetExtension(mesh, Grid**, mesh->vertGridId ); elGrid = *Mesh_GetExtension(mesh, Grid**, mesh->elGridId ); num_nodes = FeMesh_GetNodeLocalSize(mesh); inc = IArray_New(); /* mem alloc from bottom surface */ arraySize=0; /*to prevent warnings*/ if ( nDims == 2 ) arraySize = elGrid->sizes[0]; else if ( nDims == 3 ) arraySize = elGrid->sizes[0]*elGrid->sizes[self->zontalAxis]; else assert(0); local_top_vy = (double*)malloc( arraySize*sizeof(double) ); memset( local_top_vy, 0, arraySize*sizeof(double) ); local_bot_vy = (double*)malloc( arraySize*sizeof(double) ); memset( local_bot_vy, 0, arraySize*sizeof(double) ); local_height = (double*)malloc( arraySize*sizeof(double) ); memset( local_height, 0, arraySize*sizeof(double) ); local_top_cnt = (int*)malloc( arraySize*sizeof(int) ); memset( local_top_cnt, 0, arraySize*sizeof(int) ); local_bot_cnt = (int*)malloc( arraySize*sizeof(int) ); memset( local_bot_cnt, 0, arraySize*sizeof(int) ); for (ii = 0; ii < num_nodes; ii++) { FeMesh_GetNodeElements( mesh, ii, inc ); n = FeMesh_NodeDomainToGlobal(mesh, ii); Grid_Lift(grid, n, param); if ((self->surfaceIdx != -1 && param[self->vertAxis] == self->surfaceIdx) || (self->surfaceIdx == -1 && param[self->vertAxis] == grid->sizes[self->vertAxis] - 1)) { FeVariable_GetValueAtNode(self->vel_field, ii, vel); if ( self->avg ) { local_top_vy[0] += vel[self->vertAxis]; local_height[0] += Mesh_GetVertex( mesh, ii )[self->vertAxis]; local_top_cnt[0]++; } else { for (jj = 0; jj < inc->size; jj++ ) { Grid_Lift( elGrid, FeMesh_ElementDomainToGlobal( self->mesh, inc->ptr[jj] ), elParam ); /* Make sure element is below surface. */ if ( self->surfaceIdx != -1 && elParam[self->vertAxis] >= self->surfaceIdx ) continue; arrayPos = elParam[0]; if ( nDims == 3 ) arrayPos += elParam[self->zontalAxis]*elGrid->sizes[0]; local_top_vy[arrayPos] += vel[self->vertAxis]; local_height[arrayPos] += Mesh_GetVertex( mesh, ii )[self->vertAxis]; local_top_cnt[arrayPos]++; } } } if (param[self->vertAxis] == 0 ) { FeVariable_GetValueAtNode(self->vel_field, ii, vel); if ( self->avg ) { local_bot_vy[0] += vel[self->vertAxis]; local_height[0] -= Mesh_GetVertex( mesh, ii )[self->vertAxis]; local_bot_cnt[0]++; } else { for (jj = 0; jj < inc->size; jj++ ) { Grid_Lift( elGrid, FeMesh_ElementDomainToGlobal( self->mesh, inc->ptr[jj] ), elParam ); /* Make sure element is below surface. */ if ( self->surfaceIdx != -1 && elParam[self->vertAxis] >= self->surfaceIdx ) continue; arrayPos = elParam[0]; if ( nDims == 3 ) arrayPos += elParam[self->zontalAxis]*elGrid->sizes[0]; local_bot_vy[arrayPos] += vel[self->vertAxis]; local_height[arrayPos] -= Mesh_GetVertex( mesh, ii )[self->vertAxis]; local_bot_cnt[arrayPos]++; } } } } global_top_vy = (double*)malloc( arraySize*sizeof(double) ); global_bot_vy = (double*)malloc( arraySize*sizeof(double) ); global_height = (double*)malloc( arraySize*sizeof(double) ); global_top_cnt = (int*)malloc( arraySize*sizeof(int) ); global_bot_cnt = (int*)malloc( arraySize*sizeof(int) ); MPI_Allreduce(local_height, global_height, arraySize, MPI_DOUBLE, MPI_SUM, MPI_COMM_WORLD); MPI_Allreduce(local_top_vy, global_top_vy, arraySize, MPI_DOUBLE, MPI_SUM, MPI_COMM_WORLD); MPI_Allreduce(local_bot_vy, global_bot_vy, arraySize, MPI_DOUBLE, MPI_SUM, MPI_COMM_WORLD); MPI_Allreduce(local_top_cnt, global_top_cnt, arraySize, MPI_INT, MPI_SUM, MPI_COMM_WORLD); MPI_Allreduce(local_bot_cnt, global_bot_cnt, arraySize, MPI_INT, MPI_SUM, MPI_COMM_WORLD); free( local_height ); free( local_top_vy ); free( local_bot_vy ); free( local_top_cnt ); free( local_bot_cnt ); Stg_Class_Delete( inc ); *_avg_sep = (double*)malloc( arraySize*sizeof(double) ); *_avg_height = (double*)malloc( arraySize*sizeof(double) ); for ( ii = 0; ii < arraySize; ii++ ) { (*_avg_sep)[ii] = global_top_vy[ii]/(double)(global_top_cnt[ii]) - global_bot_vy[ii]/(double)(global_bot_cnt[ii]); (*_avg_height)[ii] = global_height[ii]/(double)(global_top_cnt[ii]); if (self->avg) break; } free( global_height ); free( global_top_vy ); free( global_bot_vy ); free( global_top_cnt ); free( global_bot_cnt ); }
void lecode_tools_Isostasy_CalcBasalFlow(lecode_tools_Isostasy *self) { int rank; Grid *nodeGrid, *elGrid; double *avg_sep, *avg_height; double *avg_density, *rho_zero_density; double *phi, **phi_ptr; double *node_avg_sep, *node_avg_height; double *node_avg_density, *node_rho_zero_density, *node_phi; double *global_node_avg_sep, *global_node_avg_height; double *global_node_avg_density, *global_node_rho_zero_density, *global_node_phi; double avgFlow, tmp; int param[3], nodeIdx, arraySize, arrayPos, elPos; int nDims, iterSizes[2]; IArray *inc; int ii, jj, kk; MPI_Comm_rank(MPI_COMM_WORLD, &rank); nDims = Mesh_GetDimSize( self->mesh ); nodeGrid = *Mesh_GetExtension( self->mesh, Grid**, self->mesh->vertGridId ); elGrid = *Mesh_GetExtension( self->mesh, Grid**, self->mesh->elGridId ); inc = IArray_New(); if (self->thermalSLE) { lecode_tools_Isostasy_SolveThermal(self); phi_ptr = φ } else phi_ptr = NULL; lecode_tools_Isostasy_AverageSurfaces(self, &avg_sep, &avg_height); lecode_tools_Isostasy_AverageBody(self, &avg_density, &rho_zero_density, phi_ptr); // avg_density seems to be the avg rho across the basal node columns. // rho_zero_density seems to be the avg density of the rho_zero material. if ( self->avg ) { self->flow[0] = -1.0*avg_density[0]*avg_sep[0]/rho_zero_density[0]; if (phi_ptr) self->flow[0] -= avg_height[0]*phi[0]/rho_zero_density[0]; avgFlow = self->flow[0]; } else { // nodeGrid->sizes is the dimensions of the mesh in x (0), y (1), and z(2) arraySize=0; if ( nDims == 2 ) arraySize = nodeGrid->sizes[0]; else if ( nDims == 3 ) arraySize = nodeGrid->sizes[0]*nodeGrid->sizes[self->zontalAxis]; else assert(0); // the arraysize is the base of the model, in nodes. node_avg_density = (double*)malloc( arraySize*sizeof(double) ); memset( node_avg_density, 0, arraySize*sizeof(double) ); node_rho_zero_density = (double*)malloc( arraySize*sizeof(double) ); memset( node_rho_zero_density, 0, arraySize*sizeof(double) ); node_avg_sep = (double*)malloc( arraySize*sizeof(double) ); memset( node_avg_sep, 0, arraySize*sizeof(double) ); node_avg_height = (double*)malloc( arraySize*sizeof(double) ); memset( node_avg_height, 0, arraySize*sizeof(double) ); if ( phi_ptr ) { node_phi = (double*)malloc( arraySize*sizeof(double) ); memset( node_phi, 0, arraySize*sizeof(double) ); } param[0] = param[1] = param[2] = 0; iterSizes[0] = nodeGrid->sizes[0]; iterSizes[1] = (nDims == 3) ? nodeGrid->sizes[self->zontalAxis] : 1; for ( ii = 0; ii < iterSizes[1]; ii++ ) { // Going into the 'Y' or 'Z' of the basal surface. If 2D, then this loop only goes once. for ( kk = 0; kk < iterSizes[0]; kk++) { param[self->zontalAxis] = ii; param[0] = kk; arrayPos = param[0] + param[self->zontalAxis]*nodeGrid->sizes[0]; nodeIdx = Grid_Project( nodeGrid, param ); if ( !FeMesh_NodeGlobalToDomain( self->mesh, nodeIdx, &nodeIdx ) || nodeIdx >= FeMesh_GetNodeLocalSize( self->mesh ) ) { continue; } FeMesh_GetNodeElements( self->mesh, nodeIdx, inc ); for ( jj = 0; jj < inc->size; jj++ ) { Grid_Lift( elGrid, FeMesh_ElementDomainToGlobal( self->mesh, inc->ptr[jj] ), param ); elPos = param[0]; if ( nDims == 3 ) elPos += param[self->zontalAxis]*elGrid->sizes[0]; node_avg_density[arrayPos] += avg_density[elPos]; node_rho_zero_density[arrayPos] += rho_zero_density[elPos]; node_avg_sep[arrayPos] += avg_sep[elPos]; node_avg_height[arrayPos] += avg_height[elPos]; if ( phi_ptr ) node_phi[arrayPos] += phi[elPos]; } node_avg_density[arrayPos] /= (double)inc->size; node_rho_zero_density[arrayPos] /= (double)inc->size; node_avg_sep[arrayPos] /= (double)inc->size; node_avg_height[arrayPos] /= (double)inc->size; if ( phi_ptr ) node_phi[arrayPos] /= (double)inc->size; } } global_node_avg_density = (double*)malloc( arraySize*sizeof(double) ); memset( global_node_avg_density, 0, arraySize*sizeof(double) ); global_node_rho_zero_density = (double*)malloc( arraySize*sizeof(double) ); memset( global_node_rho_zero_density, 0, arraySize*sizeof(double) ); global_node_avg_sep = (double*)malloc( arraySize*sizeof(double) ); memset( global_node_avg_sep, 0, arraySize*sizeof(double) ); global_node_avg_height = (double*)malloc( arraySize*sizeof(double) ); memset( global_node_avg_height, 0, arraySize*sizeof(double) ); if ( phi_ptr ) { global_node_phi = (double*)malloc( arraySize*sizeof(double) ); memset( global_node_phi, 0, arraySize*sizeof(double) ); } MPI_Allreduce(node_avg_density, global_node_avg_density, arraySize, MPI_DOUBLE, MPI_SUM, MPI_COMM_WORLD); MPI_Allreduce(node_rho_zero_density, global_node_rho_zero_density, arraySize, MPI_DOUBLE, MPI_SUM, MPI_COMM_WORLD); MPI_Allreduce(node_avg_sep, global_node_avg_sep, arraySize, MPI_DOUBLE, MPI_SUM, MPI_COMM_WORLD); MPI_Allreduce(node_avg_height, global_node_avg_height, arraySize, MPI_DOUBLE, MPI_SUM, MPI_COMM_WORLD); if ( phi_ptr ) MPI_Allreduce(node_phi, global_node_phi, arraySize, MPI_DOUBLE, MPI_SUM, MPI_COMM_WORLD); free( avg_sep ); free( avg_height ); free( avg_density ); free( rho_zero_density ); if ( phi_ptr ) free( phi ); Stg_Class_Delete( inc ); avgFlow = 0.0; for ( ii = 0; ii < arraySize; ii++ ) { /* param[0] = ii; nodeIdx = Grid_Project( nodeGrid, param ); if( !FeMesh_NodeGlobalToDomain( self->mesh, nodeIdx, &nodeIdx ) || nodeIdx >= FeMesh_GetNodeLocalSize( self->mesh ) ) { continue; } */ self->flow[ii] = -1.0*global_node_avg_density[ii]*global_node_avg_sep[ii]/global_node_rho_zero_density[ii]; if (phi_ptr) self->flow[ii] -= global_node_avg_height[ii]*global_node_phi[ii]/global_node_rho_zero_density[ii]; avgFlow += self->flow[ii]; } //MPI_Allreduce(&avgFlow, &tmp, 1, MPI_DOUBLE, MPI_SUM, MPI_COMM_WORLD); tmp = avgFlow; avgFlow = tmp/(double)arraySize; free( node_avg_sep ); free( node_avg_height ); free( node_avg_density ); free( node_rho_zero_density ); if ( phi_ptr ) free( node_phi ); free( global_node_avg_sep ); free( global_node_avg_height ); free( global_node_avg_density ); free( global_node_rho_zero_density ); if ( phi_ptr ) free( global_node_phi ); } if (rank == 0) { printf("===========\n"); printf("= Isostasy\n"); printf("=\n"); printf("= Average basal flow: %g\n", avgFlow); printf("===========\n"); } }
void Stokes_SLE_PenaltySolver_MakePenalty( Stokes_SLE_PenaltySolver* self, Stokes_SLE* sle, Vec* _penalty ) { Vec fVec = sle->fForceVec->vector, hVec = sle->hForceVec->vector, penalty, lambda; Mat kMat = sle->kStiffMat->matrix; FeMesh *mesh = sle->kStiffMat->rowVariable->feMesh; FeVariable *velField = sle->kStiffMat->rowVariable; SolutionVector* uVec = sle->uSolnVec; FeEquationNumber *eqNum = uVec->eqNum; IArray *inc; PetscScalar *lambdaVals, lambdaMin, *penaltyVals; int numDofs, numLocalElems, nodeCur, numLocalNodes, rank, eq; SolutionVector *solVec = sle->uSolnVec; double *velBackup; Vec vecBackup; int ii, jj, kk; MPI_Comm_rank( MPI_COMM_WORLD, &rank ); numDofs = Mesh_GetDimSize( mesh ); numLocalElems = FeMesh_GetElementLocalSize( mesh ); numLocalNodes = FeMesh_GetNodeLocalSize( mesh ); velBackup = (double*)malloc( numLocalNodes*numDofs*sizeof(double) ); for( ii = 0; ii < numLocalNodes; ii++ ) FeVariable_GetValueAtNode( velField, ii, velBackup + ii*numDofs ); VecDuplicate( hVec, &penalty ); VecGetArray( penalty, &penaltyVals ); VecDuplicate( fVec, &lambda ); MatGetDiagonal( kMat, lambda ); { PetscInt idx; PetscReal min, max; VecMin( lambda, &idx, &min ); VecMax( lambda, &idx, &max ); if( rank == 0 ) { printf( "LAMBDA RANGE:\n" ); printf( " MIN: %e\n", min ); printf( " MAX: %e\n", max ); } } vecBackup = solVec->vector; solVec->vector = lambda; SolutionVector_UpdateSolutionOntoNodes( solVec ); inc = IArray_New(); lambdaVals = (double*)malloc( numDofs*sizeof(double) ); for( ii = 0; ii < numLocalElems; ii++ ) { lambdaMin = DBL_MAX; FeMesh_GetElementNodes( mesh, ii, inc ); for( jj = 0; jj < inc->size; jj++ ) { nodeCur = inc->ptr[jj]; FeVariable_GetValueAtNode( velField, nodeCur, lambdaVals ); for( kk = 0; kk < numDofs; kk++ ) { eq = eqNum->mapNodeDof2Eq[nodeCur][kk]; if( eq == -1 ) continue; /* eq = *(int*)STreeMap_Map( eqNum->ownedMap, &eq ); VecGetValues( lambda, 1, &eq, &lambdaVal ); */ if( lambdaVals[kk] < 0.0 ) printf( "%g\n", lambdaVals[kk] ); if( lambdaVals[kk] < lambdaMin ) lambdaMin = lambdaVals[kk]; } } penaltyVals[ii] = lambdaMin; } if( lambdaVals ) free( lambdaVals ); Stg_Class_Delete( inc ); solVec->vector = vecBackup; for( ii = 0; ii < numLocalNodes; ii++ ) FeVariable_SetValueAtNode( velField, ii, velBackup + ii*numDofs ); if( velBackup ) free( velBackup ); FeVariable_SyncShadowValues( velField ); Stg_VecDestroy(&lambda ); VecRestoreArray( penalty, &penaltyVals ); VecAssemblyBegin( penalty ); VecAssemblyEnd( penalty ); { PetscInt idx; PetscReal min, max; VecMin( penalty, &idx, &min ); VecMax( penalty, &idx, &max ); if( rank == 0 ) { printf( "SEMI-PENALTY RANGE:\n" ); printf( " MIN: %e\n", min ); printf( " MAX: %e\n", max ); } } *_penalty = penalty; }
void IGraph_SetElements( void* _self, int dim, int nEls, const int* globals ) { IGraph* self = (IGraph*)_self; int rank; int nNbrs; const int *nbrs; int nSubEls; const int *subEls; int rem, netRem; int *nNbrEls, **nbrEls; IArray** isects; ISet localsObj, *locals = &localsObj; ISet remotesObj, *remotes = &remotesObj; int nCurEls, *curEls; MPI_Comm mpiComm; int n_i, e_i; assert( self && dim < self->nTDims ); assert( !nEls || globals ); assert( self->comm ); Comm_GetNeighbours( self->comm, &nNbrs, &nbrs ); if( !nNbrs ) { IGraph_SetLocalElements( self, dim, nEls, globals ); return; } ISet_Init( locals ); mpiComm = Comm_GetMPIComm( self->comm ); insist( MPI_Comm_rank( mpiComm, &rank ), == MPI_SUCCESS ); isects = AllocArray( IArray*, nNbrs ); for( n_i = 0; n_i < nNbrs; n_i++ ) isects[n_i] = IArray_New(); ISet_UseArray( locals, nEls, globals ); nSubEls = (nEls < 1000) ? nEls : 1000; rem = nEls; subEls = globals; nNbrEls = AllocArray( int, nNbrs ); nbrEls = AllocArray( int*, nNbrs ); do { Comm_AllgatherInit( self->comm, nSubEls, nNbrEls, sizeof(int) ); for( n_i = 0; n_i < nNbrs; n_i++ ) nbrEls[n_i] = AllocArray( int, nNbrEls[n_i] ); Comm_AllgatherBegin( self->comm, subEls, (void**)nbrEls ); Comm_AllgatherEnd( self->comm ); for( n_i = 0; n_i < nNbrs; n_i++ ) { for( e_i = 0; e_i < nNbrEls[n_i]; e_i++ ) { if( ISet_Has( locals, nbrEls[n_i][e_i] ) ) IArray_Append( isects[n_i], nbrEls[n_i][e_i] ); } FreeArray( nbrEls[n_i] ); } subEls += nSubEls; rem -= nSubEls; nSubEls = (rem < 1000) ? rem : 1000; insist( MPI_Allreduce( &rem, &netRem, 1, MPI_INT, MPI_SUM, mpiComm ), == MPI_SUCCESS ); } while( netRem ); FreeArray( nNbrEls ); FreeArray( nbrEls ); ISet_Init( remotes ); ISet_SetMaxSize( remotes, nEls ); for( n_i = 0; n_i < nNbrs; n_i++ ) { IArray_GetArray( isects[n_i], &nCurEls, (const int**)&curEls ); if( nbrs[n_i] < rank ) { for( e_i = 0; e_i < nCurEls; e_i++ ) { ISet_TryRemove( locals, curEls[e_i] ); ISet_TryInsert( remotes, curEls[e_i] ); } } Stg_Class_Delete( isects[n_i] ); } FreeArray( isects ); nCurEls = ISet_GetSize( locals ); curEls = AllocArray( int, nCurEls ); ISet_GetArray( locals, curEls ); ISet_Destruct( locals ); qsort( curEls, nCurEls, sizeof(int), IGraph_Cmp ); IGraph_SetLocalElements( self, dim, nCurEls, curEls ); FreeArray( curEls ); nCurEls = ISet_GetSize( remotes ); curEls = AllocArray( int, nCurEls ); ISet_GetArray( remotes, curEls ); ISet_Destruct( remotes ); qsort( curEls, nCurEls, sizeof(int), IGraph_Cmp ); IGraph_SetRemoteElements( self, dim, nCurEls, curEls ); FreeArray( curEls ); }
IArrayClass(){ inc = IArray_New(); };
void _Mesh_CentroidType_Init( Mesh_CentroidType* self ) { assert( self && Stg_CheckType( self, Mesh_CentroidType ) ); self->elMesh = NULL; self->incArray = IArray_New(); }
Variable* Mesh_GenerateENMapVar( void* mesh ) { /* Returns a Variable that stores the mapping of * [local element] [global node indices] * Assumes the mapping never changes. */ Mesh* self = (Mesh*)mesh; char* name; int n_i, e_i, nNbr, localElements, localtotal; unsigned buffy_tvs; // buffer for global node indices unsigned dim, *nbr, temp; int *numberNodesPerEl = NULL; IArray* inc = NULL; Stream* error = Journal_Register( Error_Type, (Name)self->type ); // if variable already exists return it if( self->enMapVar ) return self->enMapVar; /* go over local elementNode map to get size of data */ inc = IArray_New( ); self->localtotalNodes=0; dim = Mesh_GetDimSize( self ); localElements = Mesh_GetLocalSize( self, dim ); numberNodesPerEl = Memory_Alloc_Array( int, localElements, "Mesh::numberNodesPerEl" ); for( e_i=0 ; e_i < localElements; e_i++ ) { Mesh_GetIncidence( self, dim, (unsigned)e_i, MT_VERTEX, inc ); nNbr = IArray_GetSize( inc ); nbr = IArray_GetPtr( inc ); numberNodesPerEl[e_i] = nNbr; self->localtotalNodes += nNbr; } /* Create the Variable data structure, int[nbrNodesPerEl*local element count] * Note: this is stored in a 1D array - so whatever read or writes to this variable * needs to know how to parse it. */ self->e_n = Memory_Alloc_Array( int, self->localtotalNodes, "Mesh::nodeConn" ); Stg_asprintf( &name, "%s-%s", self->name, "nodeConn" ); self->enMapVar = Variable_NewScalar( name, NULL, Variable_DataType_Int, &self->localtotalNodes, NULL, (void**)&self->e_n, NULL ); Stg_Component_Build(self->enMapVar, NULL, False); Stg_Component_Initialise(self->enMapVar, NULL, False); free(numberNodesPerEl); free(name); // Evaluate the global indices for the local nodes localtotal=0; for( e_i=0; e_i<localElements; e_i++ ) { Mesh_GetIncidence( self, dim, (unsigned)e_i, MT_VERTEX, inc ); nNbr = IArray_GetSize( inc ); nbr = IArray_GetPtr( inc ); for( n_i=0; n_i< nNbr; n_i++ ) { buffy_tvs = Mesh_DomainToGlobal( self, MT_VERTEX, nbr[n_i] ); Variable_SetValue( self->enMapVar, localtotal, (void*)&buffy_tvs ); localtotal++; } } Stg_Class_Delete( inc ); // return new variable return self->enMapVar; }