void _Mesh_Build( void* mesh, void* data ) { Mesh* self = (Mesh*)mesh; unsigned nDims; unsigned d_i; assert( self ); if( self->generator ) { Stg_Component_Build( self->generator, data, False ); MeshGenerator_Generate( self->generator, self, data ); } if( self->algorithms ) Stg_Component_Build( self->algorithms, data, False ); nDims = Mesh_GetDimSize( self ); if( !nDims ){ self->isBuilt = False; return; } self->topoDataInfos = Memory_Alloc_Array( ExtensionManager*, nDims, "mesh::topoDataInfos" ); self->topoDatas = Memory_Alloc_Array( void*, nDims, "mesh::topoDatas" ); for( d_i = 0; d_i < nDims; d_i++ ) { char name[20]; unsigned size; if( !UIntMap_Map( self->topoDataSizes, d_i, &size ) || !size || !Mesh_GetDomainSize( self, d_i ) ) { self->topoDataInfos[d_i] = NULL; self->topoDatas[d_i] = NULL; continue; } sprintf( name, "topoData(%d)", d_i ); self->topoDataInfos[d_i] = ExtensionManager_New_OfStruct( name, size ); self->topoDatas[d_i] = (void*)ExtensionManager_Malloc( self->topoDataInfos[d_i], Mesh_GetDomainSize( self, d_i ) ); } /* ** Set up the geometric information. */ self->minAxialSep = Memory_Alloc_Array( double, nDims, "Mesh::minAxialSep" ); self->minLocalCrd = Memory_Alloc_Array( double, nDims, "Mesh::minLocalCrd" ); self->maxLocalCrd = Memory_Alloc_Array( double, nDims, "Mesh::maxLocalCrd" ); self->minDomainCrd = Memory_Alloc_Array( double, nDims, "Mesh::minLocalCrd" ); self->maxDomainCrd = Memory_Alloc_Array( double, nDims, "Mesh::maxLocalCrd" ); self->minGlobalCrd = Memory_Alloc_Array( double, nDims, "Mesh::minGlobalCrd" ); self->maxGlobalCrd = Memory_Alloc_Array( double, nDims, "Mesh::maxGlobalCrd" ); Mesh_DeformationUpdate( self ); }
Cell_Index _ElementCellLayout_MapElementIdToCellId( void* elementCellLayout, unsigned element_dI ) { #ifdef CAUTIOUS { ElementCellLayout* self = (ElementCellLayout*)elementCellLayout; Stream* errorStr = Journal_Register( Error_Type, (Name)self->type ); Journal_Firewall( element_dI < Mesh_GetDomainSize( self->mesh, Mesh_GetDimSize( self->mesh ) ), errorStr, "Error - in %s(): User asked " "for cell corresponding to element %d, but the mesh that this cell layout is based on only " "has %d elements.\n", __func__, element_dI, Mesh_GetDomainSize( self->mesh, Mesh_GetDimSize( self->mesh ) ) ); } #endif return element_dI; }
void Mesh_Sync( void* mesh ) { Mesh* self = (Mesh*)mesh; const Sync* sync; int nDims, nLocals, nDomains; assert( self ); sync = Mesh_GetSync( self, 0 ); nDims = Mesh_GetDimSize( self ); nLocals = Mesh_GetLocalSize( self, 0 ); nDomains = Mesh_GetDomainSize( self, 0 ); if (nDomains > nLocals) // only perform this where where the domain size is greater than the local size... ie running in parallel Sync_SyncArray( sync, Mesh_GetVertex( self, 0 ), nDims * sizeof(double), Mesh_GetVertex( self, nLocals ), nDims * sizeof(double), nDims * sizeof(double) ); /* TODO if( self->dataSyncArrays ) { unsigned d_i; for( d_i = 0; d_i < Mesh_GetDimSize( self ); d_i++ ) { if( self->dataSyncArrays[d_i] ) Decomp_Sync_Array_Sync( self->dataSyncArrays[d_i] ); } } */ }
void _SphericalGenerator_GenElementTypes( void* meshGenerator, Mesh* mesh ) { SphericalGenerator* self = (SphericalGenerator*)meshGenerator; Stream* stream; unsigned nDomainEls; unsigned e_i; assert( self && Stg_CheckType( self, SphericalGenerator ) ); stream = Journal_Register( Info_Type, (Name)self->type ); Journal_Printf( stream, "Generating element types...\n" ); Stream_Indent( stream ); mesh->nElTypes = 1; mesh->elTypes = Memory_Alloc_Array( Mesh_ElementType*, mesh->nElTypes, "Mesh::elTypes" ); mesh->elTypes[0] = (Mesh_ElementType*)Mesh_HexType_New(); Mesh_ElementType_SetMesh( mesh->elTypes[0], mesh ); nDomainEls = Mesh_GetDomainSize( mesh, Mesh_GetDimSize( mesh ) ); mesh->elTypeMap = Memory_Alloc_Array( unsigned, nDomainEls, "Mesh::elTypeMap" ); for( e_i = 0; e_i < nDomainEls; e_i++ ) mesh->elTypeMap[e_i] = 0; Mesh_SetAlgorithms( mesh, Mesh_SphericalAlgorithms_New( "", NULL ) ); MPI_Barrier( self->mpiComm ); Journal_Printf( stream, "... element types are '%s',\n", mesh->elTypes[0]->type ); Journal_Printf( stream, "... mesh algorithm type is '%s',\n", mesh->algorithms->type ); Journal_Printf( stream, "... done.\n" ); Stream_UnIndent( stream ); }
void _AnalyticFeVariable_Build( void* analyticFeVariable, void* data ) { AnalyticFeVariable* self = (AnalyticFeVariable*)analyticFeVariable; DomainContext* context = self->context; DofLayout* dofLayout = NULL; Name name, varName[9]; Variable* variable = NULL; Variable* baseVariable = NULL; FeMesh* referenceMesh = NULL; unsigned nDomainVerts; Index var_I, node_I; double* arrayPtr; Dof_Index componentsCount; Variable_Register* variable_Register = NULL;; _FeVariable_Build( self, data ); context = self->context; variable_Register = context->variable_Register; referenceMesh = self->numericField->feMesh; componentsCount = self->numericField->fieldComponentCount; name = Stg_Object_AppendSuffix( self->numericField, (Name)"AnalyticVariable" ); nDomainVerts = Mesh_GetDomainSize( referenceMesh, MT_VERTEX ); if( componentsCount == 1 ) { arrayPtr = Memory_Alloc_Array_Unnamed( double, nDomainVerts ); baseVariable = Variable_NewScalar( name, (AbstractContext*)context, Variable_DataType_Double, (Index*)&nDomainVerts, NULL, (void**)&arrayPtr, variable_Register ); }
void SROpGenerator_GenLevelEqNums( SROpGenerator* self, unsigned level ) { Mesh* cMesh; unsigned* nNodalDofs; unsigned nDomainNodes, nLocalNodes; DofLayout* dofLayout; unsigned** dstArray; unsigned curEqNum; unsigned maxDofs; unsigned topNode; unsigned base, subTotal; MPI_Comm comm; unsigned nProcs, rank; MPI_Status status; unsigned* tuples; Sync* sync; unsigned n_i, dof_i; assert( self && Stg_CheckType( self, SROpGenerator ) ); assert( self->meshes && self->topMaps && self->eqNums ); assert( level < self->nLevels ); cMesh = self->meshes[level]; nDomainNodes = Mesh_GetDomainSize( cMesh, MT_VERTEX ); nLocalNodes = Mesh_GetLocalSize( cMesh, MT_VERTEX ); dofLayout = self->fineEqNum->dofLayout; comm = Comm_GetMPIComm( Mesh_GetCommTopology( cMesh, MT_VERTEX ) ); MPI_Comm_size( comm, (int*)&nProcs ); MPI_Comm_rank( comm, (int*)&rank ); /* Allocate for destination array. */ nNodalDofs = AllocArray( unsigned, nDomainNodes ); for( n_i = 0; n_i < nDomainNodes; n_i++ ) nNodalDofs[n_i] = dofLayout->dofCounts[self->topMaps[level][n_i]]; dstArray = AllocComplex2D( unsigned, nDomainNodes, nNodalDofs ); /* Build initial destination array and store max dofs. */ curEqNum = 0; maxDofs = 0; for( n_i = 0; n_i < nLocalNodes; n_i++ ) { if( nNodalDofs[n_i] > maxDofs ) maxDofs = nNodalDofs[n_i]; topNode = self->topMaps[level][n_i]; for( dof_i = 0; dof_i < nNodalDofs[n_i]; dof_i++ ) { if( self->fineEqNum->mapNodeDof2Eq[topNode][dof_i] != (unsigned)-1 ) dstArray[n_i][dof_i] = curEqNum++; else dstArray[n_i][dof_i] = (unsigned)-1; } } /* Order the equation numbers based on processor rank; cascade counts forward. */ base = 0; subTotal = curEqNum; if( rank > 0 ) { insist( MPI_Recv( &base, 1, MPI_UNSIGNED, rank - 1, 6669, comm, &status ), == MPI_SUCCESS ); subTotal = base + curEqNum; }
double* Mesh_GetVertex( void* mesh, unsigned domain ) { Mesh* self = (Mesh*)mesh; assert( self ); assert( domain < Mesh_GetDomainSize( self, MT_VERTEX ) ); assert( self->vertices ); return self->vertices + domain*Mesh_GetDimSize(self); }
Cell_Index _ElementCellLayout_CellOf( void* elementCellLayout, void* _particle ) { ElementCellLayout* self = (ElementCellLayout*)elementCellLayout; GlobalParticle* particle = (GlobalParticle*)_particle; unsigned elInd; if( !Mesh_SearchElements( self->mesh, particle->coord, &elInd ) ) elInd = Mesh_GetDomainSize( self->mesh, Mesh_GetDimSize( self->mesh ) ); return elInd; }
Cell_Index _ElementCellLayout_CellOf_Irregular( void* elementCellLayout, void* _particle ) { /* algorithm for irregular searches, this method uses the existing particle information to optimise the search */ ElementCellLayout* self = (ElementCellLayout*)elementCellLayout; GlobalParticle* particle = (GlobalParticle*)_particle; unsigned elInd, elDim, cell_id; Mesh* mesh = self->mesh; cell_id = particle->owningCell; /* check if particle already has an owning cell, for search optimisation */ if( cell_id < Mesh_GetDomainSize( mesh, Mesh_GetDimSize( mesh ) ) ) { IArray *inc = self->incArray; int el_i; unsigned nEls; int *neighbourEls; /* search current cell */ if( Mesh_ElementHasPoint( mesh, cell_id, particle->coord, &elDim, &elInd ) ) { return elInd; } /* search neighbouring cells */ Mesh_GetIncidence( mesh, Mesh_GetDimSize( mesh ), cell_id, Mesh_GetDimSize(mesh), inc ); nEls = IArray_GetSize( inc ); neighbourEls = IArray_GetPtr( inc ); for( el_i = 0; el_i<nEls; el_i++ ) { if( Mesh_ElementHasPoint( mesh, neighbourEls[el_i], particle->coord, &elDim, &elInd ) ) { return elInd; } } } // brute force search if( !Mesh_SearchElements( self->mesh, particle->coord, &elInd ) ) elInd = Mesh_GetDomainSize( self->mesh, Mesh_GetDimSize( self->mesh ) ); return elInd; }
Mesh_ElementType* Mesh_GetElementType( void* mesh, unsigned element ) { Mesh* self = (Mesh*)mesh; assert( self ); assert( element < Mesh_GetDomainSize( self, Mesh_GetDimSize( self ) ) ); assert( self->elTypeMap ); assert( self->elTypeMap[element] < self->nElTypes ); assert( self->elTypes ); return self->elTypes[self->elTypeMap[element]]; }
void _HeatingForce_Build( void* heatingForce, void* data ) { HeatingForce* self = (HeatingForce*)heatingForce; unsigned nDomainVerts; Stg_Component_Build( self->feMesh, data, False ); nDomainVerts = Mesh_GetDomainSize( self->feMesh, MT_VERTEX ); self->dataVariable = Variable_NewScalar( "dataVariable", self->context, Variable_DataType_Double, &nDomainVerts, NULL, (void**)&self->data, self->context->variable_Register ); _ParticleFeVariable_Build( self, data ); DofLayout_AddAllFromVariableArray( self->dofLayout, 1, &self->dataVariable ); }
Bool Mesh_ElementHasPoint( void* mesh, unsigned element, double* point, MeshTopology_Dim* topodim, unsigned* ind ) { Mesh* self = (Mesh*)mesh; assert( self ); assert( element < Mesh_GetDomainSize( self, Mesh_GetDimSize( self ) ) ); assert( self->elTypeMap ); assert( self->elTypeMap[element] < self->nElTypes ); assert( self->elTypes[self->elTypeMap[element]] ); return Mesh_ElementType_ElementHasPoint( self->elTypes[self->elTypeMap[element]], element, point, topodim, ind ); }
void Mesh_DeformationUpdate( void* mesh ) { Mesh* self = (Mesh*)mesh; assert( self ); if( Mesh_GetDomainSize( self, 0 ) ) { self->minSep = Mesh_Algorithms_GetMinimumSeparation( self->algorithms, self->minAxialSep ); Mesh_Algorithms_GetLocalCoordRange( self->algorithms, self->minLocalCrd, self->maxLocalCrd ); Mesh_Algorithms_GetDomainCoordRange( self->algorithms, self->minDomainCrd, self->maxDomainCrd ); Mesh_Algorithms_GetGlobalCoordRange( self->algorithms, self->minGlobalCrd, self->maxGlobalCrd ); Mesh_Algorithms_Update( self->algorithms ); Mesh_ElementType_Update( self->elTypes[0] ); } }
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 SROpGenerator_GenLevelTopMap( SROpGenerator* self, unsigned level ) { Stream* errorStream = Journal_Register( ErrorStream_Type, (Name)"SROpGenerator::GenLevelTopMap" ); Mesh *fMesh, *cMesh; unsigned nDomainNodes; unsigned nLevels; unsigned nDims; unsigned nearest; double *cVert, *fVert; unsigned d_i, n_i; assert( self && Stg_CheckType( self, SROpGenerator ) ); assert( self->meshes ); assert( level < self->nLevels ); fMesh = self->meshes[level + 1]; cMesh = self->meshes[level]; nDims = Mesh_GetDimSize( fMesh ); nLevels = self->nLevels; nDomainNodes = Mesh_GetDomainSize( cMesh, MT_VERTEX ); self->topMaps[level] = ReallocArray( self->topMaps[level], unsigned, nDomainNodes ); for( n_i = 0; n_i < nDomainNodes; n_i++ ) { cVert = Mesh_GetVertex( cMesh, n_i ); nearest = Mesh_NearestVertex( fMesh, cVert ); fVert = Mesh_GetVertex( fMesh, nearest ); for( d_i = 0; d_i < nDims; d_i++ ) { if( !Num_Approx( cVert[d_i], fVert[d_i] ) ) break; } Journal_Firewall( d_i == nDims, errorStream, "\n" \ "*****************************************************************\n" \ "* Error: The finest grid could not be sub-sampled to all coarse *\n" \ "* levels. This is due to the size of the finest grid. *\n" \ "*****************************************************************\n" \ "\n" ); if( level < nLevels - 2 ) self->topMaps[level][n_i] = self->topMaps[level + 1][nearest]; else self->topMaps[level][n_i] = nearest; } }
Index _MeshVariable_GetMeshArraySize( void* meshVariable ) { MeshVariable* self = (MeshVariable*)meshVariable; return Mesh_GetDomainSize( self->mesh, self->topoDim ); }
void WallVCSuite_TestWallVC( WallVCSuiteData* data ) { unsigned nDomains; unsigned nDims = 3; unsigned meshSize[3] = {3, 3, 3}; int procToWatch; double minCrds[3] = {0.0, 0.0, 0.0}; double maxCrds[3] = {1.0, 1.0, 1.0}; char* vcKey[] = {"WallVC_Front", "WallVC_Back", "WallVC_Left", "WallVC_Right", "WallVC_Top", "WallVC_Bottom"}; char* vcKeyName[] = {"WallVC_FrontName", "WallVC_BackName", "WallVC_LeftName", "WallVC_RightName", "WallVC_TopName", "WallVC_BottomName"}; char* varName[] = {"x", "y", "z", "vx", "vy", "vz", "temp"}; char input_file[PCU_PATH_MAX]; char expected_file[PCU_PATH_MAX]; Mesh* mesh; Variable_Register* variable_Register; ConditionFunction* quadCF; ConditionFunction* expCF; ConditionFunction_Register* conFunc_Register; ExtensionManager_Register* extensionMgr_Register; Dictionary* dictionary; Dictionary* sources; Stream* stream; XML_IO_Handler* io_handler; Variable* var[7]; double* array[7]; VariableCondition* vc; Index i; procToWatch = data->nProcs >=2 ? 1 : 0; io_handler = XML_IO_Handler_New(); stream = Journal_Register( Info_Type, (Name)"WallVCStream" ); Stream_RedirectFile( stream, "testWallVC.dat" ); dictionary = Dictionary_New(); sources = Dictionary_New(); Dictionary_Add( dictionary, (Dictionary_Entry_Key)"outputPath", Dictionary_Entry_Value_FromString("./output") ); /* Input file */ pcu_filename_input( "wallVC.xml", input_file ); IO_Handler_ReadAllFromFile( io_handler, input_file, dictionary, sources ); fflush( stdout ); extensionMgr_Register = ExtensionManager_Register_New(); /* Create a mesh. */ mesh = (Mesh*) WallVCSuite_buildMesh( nDims, meshSize, minCrds, maxCrds, extensionMgr_Register ); nDomains = Mesh_GetDomainSize( mesh, MT_VERTEX ); /* Create CF stuff */ quadCF = ConditionFunction_New( WallVCSuite_quadratic, (Name)"quadratic", NULL ); expCF = ConditionFunction_New( WallVCSuite_exponential, (Name)"exponential", NULL); conFunc_Register = ConditionFunction_Register_New( ); ConditionFunction_Register_Add(conFunc_Register, quadCF); ConditionFunction_Register_Add(conFunc_Register, expCF); /* Create variable register */ variable_Register = Variable_Register_New(); /* Create variables */ for (i = 0; i < 6; i++) { array[i] = Memory_Alloc_Array( double, nDomains, "array[i]" ); var[i] = Variable_NewScalar( varName[i], NULL, Variable_DataType_Double, (Index*)&nDomains, NULL, (void**)&array[i], 0 ); Variable_Register_Add(variable_Register, var[i]); } array[6] = Memory_Alloc_Array( double, nDomains * 5, "array[6]" ); var[6] = Variable_NewVector( varName[6], NULL, Variable_DataType_Double, 5, &nDomains, NULL, (void**)&array[6], 0 ); Variable_Register_Add(variable_Register, var[6]); Variable_Register_BuildAll(variable_Register); for (i = 0; i < 6; i++) { Index j, k; vc = (VariableCondition*) WallVC_New( vcKeyName[i], NULL, vcKey[i], variable_Register, conFunc_Register, dictionary, mesh ); Stg_Component_Build( vc, 0, False ); for (j = 0; j < 6; j++) memset(array[j], 0, sizeof(double)* nDomains ); memset(array[6], 0, sizeof(double)* nDomains * 5); VariableCondition_Apply(vc, NULL); if (data->rank == procToWatch) { Journal_Printf( stream,"Testing for %s\n", vcKey[i]); for (j = 0; j < 6; j++) { Journal_Printf( stream,"\nvar[%u]: %.2lf", j, array[j][0]); for (k = 1; k < nDomains; k++) Journal_Printf( stream,", %.2lf", array[j][k]); } Journal_Printf( stream,"\nvar[6]: %.2lf", array[6][0]); for (j = 1; j < nDomains*5; j++) Journal_Printf( stream,", %.2lf", array[6][j]); Journal_Printf( stream,"\n\n"); for (j = 0; j < 7; j++) { for (k = 0; k < nDomains; k++) Journal_Printf( stream,"%s ", VariableCondition_IsCondition(vc, k, j) ? "True " : "False"); Journal_Printf( stream,"\n"); } Journal_Printf( stream,"\n"); for (j = 0; j < 7; j++) { for (k = 0; k < nDomains; k++) { VariableCondition_ValueIndex valIndex; valIndex = VariableCondition_GetValueIndex(vc, k, j); if (valIndex != (unsigned)-1) Journal_Printf( stream,"%03u ", valIndex); else Journal_Printf( stream,"XXX "); } Journal_Printf( stream,"\n"); } Journal_Printf( stream,"\n"); } Stg_Class_Delete(vc); } if (data->rank == procToWatch) { pcu_filename_expected( "testWallVC.expected", expected_file ); pcu_check_fileEq( "testWallVC.dat", expected_file ); remove( "testWallVC.dat" ); } Stg_Class_Delete(variable_Register); for (i = 0; i < 7; i++) { Stg_Class_Delete(var[i]); if (array[i]) Memory_Free(array[i]); } Stg_Class_Delete(extensionMgr_Register); Stg_Class_Delete(io_handler); Stg_Class_Delete(conFunc_Register); Stg_Class_Delete(quadCF); Stg_Class_Delete(expCF); Stg_Class_Delete(dictionary); Stg_Class_Delete(sources); FreeObject( mesh ); }