void _ConvexHull_Init( void* convexHull, Coord_List vertexList, Index vertexCount) { ConvexHull* self = (ConvexHull*)convexHull; Index numberOfFaces; Index dimensions; /* this probably doesn't need to be here */ Index vertex_I; double tmpVector1[3]; double tmpVector2[3]; double tmpVector3[3]; dimensions = 3; /* Copy vertexCount */ self->vertexCount = vertexCount; /* Copy vertexList */ self->vertexList = Memory_Alloc_Array( Coord, vertexCount, "vertexList" ); memcpy( self->vertexList , vertexList, sizeof(Coord) * vertexCount ); /* Now Construct normal and store them in self->facesList */ /* 1st allocate memory */ if(vertexCount == 3) numberOfFaces = 3; else numberOfFaces = 4; self->facesList = Memory_Alloc_Array( XYZ, numberOfFaces, "facesList" ); /* 2nd Calculate Normals on faces */ /* in 2-D */ if( numberOfFaces == 3 ) { for( vertex_I = 0; vertex_I < vertexCount ; vertex_I++ ) { StGermain_VectorSubtraction(tmpVector1, vertexList[ vertex_I % 3 ], vertexList[ (vertex_I+1) % 3 ], dimensions); StGermain_VectorSubtraction(tmpVector2, vertexList[ vertex_I % 3 ], vertexList[ (vertex_I+2) % 3 ], dimensions); tmpVector3[0] = tmpVector1[1]; tmpVector3[1] = -1 * tmpVector1[0]; tmpVector3[2] = 0; /* Now Vec3 is possibly normal vector */ if( StGermain_VectorDotProduct(tmpVector3, tmpVector2, dimensions) < 0 ) { tmpVector3[0] = -1*tmpVector3[0]; tmpVector3[1] = -1 * tmpVector3[1]; } memcpy( self->facesList[ vertex_I ], tmpVector3, sizeof(XYZ) ); } } else { for( vertex_I = 0 ; vertex_I < vertexCount ; vertex_I++ ) { StGermain_NormalToPlane( tmpVector3, vertexList[ vertex_I % 4], vertexList[ (vertex_I+1) % 4], vertexList[ (vertex_I+2) % 4]); StGermain_VectorSubtraction( tmpVector2, vertexList[ vertex_I % 4 ], vertexList[ (vertex_I+3) % 4 ], dimensions); if( StGermain_VectorDotProduct(tmpVector3, tmpVector2, dimensions) < 0 ) { Vec_Div3D( tmpVector3, tmpVector3, -1.0 ); } memcpy( self->facesList[ vertex_I ], tmpVector3, sizeof(XYZ) ); } } }
void _VariableCondition_Build( void* variableCondition, void* data ) { VariableCondition* self = (VariableCondition*)variableCondition; VariableCondition_ValueIndex val_I; Index i; /* Read the dictionary */ self->_readDictionary( self, self->dictionary ); /* Obtain the set */ self->_set = self->_getSet(self); if (self->_set) IndexSet_GetMembers(self->_set, &self->indexCount, &self->indexTbl); else { self->indexCount = 0; self->indexTbl = NULL; } /* Only build the index related tables if there are active BCs */ if ( self->indexCount ) { /* Build the variable to condition table */ self->vcVarCountTbl = Memory_Alloc_Array( VariableCondition_VariableIndex, self->indexCount, "VC->vcVarCountTbl" ); for (i = 0; i < self->indexCount; i++) { /* For the index, get the number of "variables" that have been assigned conditions */ self->vcVarCountTbl[i] = self->_getVariableCount(self, self->indexTbl[i]); } self->vcTbl = Memory_Alloc_2DComplex( VariableCondition_Tuple, self->indexCount, self->vcVarCountTbl, "VC->vcTbl" ); for ( i = 0; i < self->indexCount; i++ ) { VariableCondition_VariableIndex vcVar_I; for ( vcVar_I = 0; vcVar_I < self->vcVarCountTbl[i]; vcVar_I++ ) { Variable* var; /* For the index's variable, get the variable i.d. and value i.d. */ self->vcTbl[i][vcVar_I].varIndex = self->_getVariableIndex(self, self->indexTbl[i], vcVar_I); self->vcTbl[i][vcVar_I].valIndex = self->_getValueIndex(self, self->indexTbl[i], vcVar_I); /* Force the building of the variable (to be safe) */ var = self->variable_Register->_variable[self->vcTbl[i][vcVar_I].varIndex]; Stg_Component_Build( var, data, False ); } } } self->valueCount = self->_getValueCount(self); self->valueTbl = Memory_Alloc_Array( VariableCondition_Value, self->valueCount, "VC->valueTbl" ); for (val_I = 0; val_I < self->valueCount; val_I++) self->valueTbl[val_I] = self->_getValue(self, val_I); /* Build mapping. */ self->mapping = UIntMap_New(); for( i = 0; i < self->indexCount; i++ ) UIntMap_Insert( self->mapping, self->indexTbl[i], i ); }
void* _DofLayout_Copy( void* dofLayout, void* dest, Bool deep, Name nameExt, PtrMap* ptrMap ) { DofLayout* self = (DofLayout*)dofLayout; DofLayout* newDofLayout; PtrMap* map = ptrMap; Bool ownMap = False; if( !map ) { map = PtrMap_New( 10 ); ownMap = True; } newDofLayout = (DofLayout*)_Stg_Component_Copy( self, dest, deep, nameExt, map ); newDofLayout->_variableRegister = self->_variableRegister; newDofLayout->_numItemsInLayout = self->_numItemsInLayout; newDofLayout->_totalVarCount = self->_totalVarCount; if( deep ) { if( (newDofLayout->_variableEnabledSets = PtrMap_Find( map, self->_variableEnabledSets )) == NULL && self->_variableEnabledSets ) { Index set_I; newDofLayout->_variableEnabledSets = Memory_Alloc_Array( IndexSet*, newDofLayout->_totalVarCount, "DofLayout->_variableEnabledSets" ); for( set_I = 0; set_I < newDofLayout->_totalVarCount; set_I++ ) { newDofLayout->_variableEnabledSets[set_I] = (IndexSet*)Stg_Class_Copy( self->_variableEnabledSets[set_I], NULL, deep, nameExt, map ); } PtrMap_Append( map, self->_variableEnabledSets, newDofLayout->_variableEnabledSets ); } if( (newDofLayout->_varIndicesMapping = PtrMap_Find( map, self->_varIndicesMapping )) == NULL && self->_varIndicesMapping ) { newDofLayout->_varIndicesMapping = Memory_Alloc_Array( Variable_Index, newDofLayout->_totalVarCount, "DofLayout->_varIndicesMapping" ); memcpy( newDofLayout->_varIndicesMapping, self->_varIndicesMapping, sizeof(Variable_Index) * newDofLayout->_totalVarCount ); PtrMap_Append( map, self->_varIndicesMapping, newDofLayout->_varIndicesMapping ); } if( (newDofLayout->dofCounts = PtrMap_Find( map, self->dofCounts )) == NULL && self->dofCounts ) { newDofLayout->dofCounts = Memory_Alloc_Array( Index, newDofLayout->_numItemsInLayout, "DofLayout->dofCounts" ); memcpy( newDofLayout->dofCounts, self->dofCounts, sizeof(Index) * newDofLayout->_numItemsInLayout ); PtrMap_Append( map, self->dofCounts, newDofLayout->dofCounts ); } if( (newDofLayout->varIndices = PtrMap_Find( map, self->varIndices )) == NULL && self->varIndices ) { Index idx_I; newDofLayout->varIndices = Memory_Alloc_2DComplex( Variable_Index, newDofLayout->_numItemsInLayout, self->dofCounts, "DofLayout->varIndices" ); for( idx_I = 0; idx_I < newDofLayout->_numItemsInLayout; idx_I++ ) { memcpy( newDofLayout->varIndices[idx_I], self->varIndices[idx_I], sizeof(Variable_Index) * newDofLayout->dofCounts[idx_I] ); } PtrMap_Append( map, self->varIndices, newDofLayout->varIndices ); } }
void _SingleCellLayout_InitialiseGlobalCellPointPositions( SingleCellLayout* self ) { Cell_PointIndex point_I = 0; Coord tempCoord; double* currPointCoord = NULL; Index i, j, k; /* loop iterators for each dimension */ tempCoord[0] = self->min[I_AXIS]; tempCoord[1] = self->min[J_AXIS]; tempCoord[2] = self->min[K_AXIS]; self->cellPointCoords = Memory_Alloc_Array( Coord, self->pointCount, "SingleCellLayout->cellPoints" ); /* Now generate the coordinates */ for ( k=0; k <= self->dimExists[K_AXIS]; k++ ) { for (j=0; j <= self->dimExists[J_AXIS]; j++ ) { for (i=0; i <= self->dimExists[I_AXIS]; i++ ) { currPointCoord = self->cellPointCoords[ RegularMeshUtils_ascendingIJK_ToHughesNodeNumberMap[point_I++] ]; currPointCoord[I_AXIS] = tempCoord[I_AXIS]; currPointCoord[J_AXIS] = tempCoord[J_AXIS]; currPointCoord[K_AXIS] = tempCoord[K_AXIS]; /* flip/flop the i for next time */ tempCoord[I_AXIS] = ( self->min[I_AXIS] == tempCoord[I_AXIS] ) ? self->max[I_AXIS] : self->min[I_AXIS]; } /* flip/flop the j for next time */ tempCoord[J_AXIS] = ( self->min[J_AXIS] == tempCoord[J_AXIS] ) ? self->max[J_AXIS] : self->min[J_AXIS]; } /* flip/flop the k for next time */ tempCoord[K_AXIS] = ( self->min[K_AXIS] == tempCoord[K_AXIS] ) ? self->max[K_AXIS] : self->min[K_AXIS]; } }
void IndexMap_Append( void* indexMap, Index key, Index idx ) { IndexMap* self = (IndexMap*)indexMap; unsigned newTupleCnt; assert( self && key != -1 && idx != -1 ); if( IndexMap_Find( self, key ) != -1 ) { return; } newTupleCnt = self->tupleCnt + 1; if( newTupleCnt >= self->maxTuples ) { unsigned factor; IndexMapTuple* newTuples; factor = ceil( (float)(newTupleCnt - self->maxTuples) / (float)self->delta ); self->maxTuples += factor * self->delta; newTuples = Memory_Alloc_Array( IndexMapTuple, self->maxTuples, "IndexMap->tupleTbl" ); assert( newTuples ); /* TODO change this */ if( self->tupleTbl ) { memcpy( newTuples, self->tupleTbl, sizeof(IndexMapTuple) * self->tupleCnt ); Memory_Free( self->tupleTbl ); } self->tupleTbl = newTuples; } self->tupleTbl[self->tupleCnt].key = key; self->tupleTbl[self->tupleCnt].idx = idx; self->tupleCnt = newTupleCnt; }
void ElementCellLayoutSuite_TestElementCellLayout( ElementCellLayoutSuiteData* data ) { int procToWatch = data->nProcs > 1 ? 1 : 0; Cell_Index cell; Element_DomainIndex element; GlobalParticle testParticle; if( data->rank == procToWatch ) { for( element = 0; element < Mesh_GetLocalSize( data->mesh, data->nDims ); element++ ) { Cell_PointIndex count; Cell_Points cellPoints; cell = CellLayout_MapElementIdToCellId( data->elementCellLayout, element ); pcu_check_true( cell == element ); count = data->elementCellLayout->_pointCount( data->elementCellLayout, cell ); cellPoints = Memory_Alloc_Array( Cell_Point, count, "cellPoints" ); /* for the element cell layout, the elements map to cells as 1:1, as such the "points" which define the cell as the * same as the "nodes" which define the element */ data->elementCellLayout->_initialisePoints( data->elementCellLayout, cell, count, cellPoints ); testParticle.coord[0] = ( (cellPoints[0])[0] + (cellPoints[1])[0] ) / 2; testParticle.coord[1] = ( (cellPoints[0])[1] + (cellPoints[2])[1] ) / 2; testParticle.coord[2] = ( (cellPoints[0])[2] + (cellPoints[4])[2] ) / 2; pcu_check_true( CellLayout_IsInCell( data->elementCellLayout, cell, &testParticle ) ); testParticle.coord[0] = (cellPoints[count-2])[0] + 1; testParticle.coord[1] = (cellPoints[count-2])[1] + 1; testParticle.coord[2] = (cellPoints[count-2])[2] + 1; pcu_check_true( !CellLayout_IsInCell( data->elementCellLayout, cell, &testParticle ) ); Memory_Free( cellPoints ); } } }
/* Initialisation implementation */ void _Stg_ObjectList_Init( Stg_ObjectList* self, Index initialSize, Index delta ) { self->count = 0; self->_size = initialSize; self->_delta = delta; self->data = (Stg_ObjectPtr*)Memory_Alloc_Array( Stg_ObjectPtr, initialSize, "ObjectList->data" ); self->_noJournalingInCopy = False; }
void Stg_ObjectList_PrintSimilar( void* objectList, Name name, void* _stream, unsigned int number ) { Stg_ObjectList* self = (Stg_ObjectList*)objectList; Stream* stream = (Stream*)_stream; Stg_ObjectList_SimilarityObject* similarityArray; float stringLength = (float) strlen( name ); float objectStringLength; Index object_I; unsigned int substringLength; similarityArray = Memory_Alloc_Array( Stg_ObjectList_SimilarityObject, self->count, "similarityArray"); for ( object_I = 0 ; object_I < self->count ; object_I++ ) { substringLength = Stg_LongestMatchingSubsequenceLength( self->data[object_I]->name, name, False ); objectStringLength = (float) strlen( self->data[object_I]->name ); similarityArray[ object_I ].objectPtr = self->data[object_I]; similarityArray[ object_I ].percentageSimilar = (float) substringLength * 100.0 / MAX( objectStringLength, stringLength ); } qsort( similarityArray, (size_t)self->count, sizeof( Stg_ObjectList_SimilarityObject ), _Stg_ObjectList_SimilarityCompare ); if ( number > self->count ) number = self->count; for ( object_I = 0 ; object_I < number ; object_I++ ) { Journal_Printf( stream, "%s (%.2f%% similar)\n", similarityArray[ object_I ].objectPtr->name, similarityArray[ object_I ].percentageSimilar ); } Memory_Free( similarityArray ); }
void ParticleShadowSync_GetCountOfParticlesOutsideDomainPerProcessor( ParticleShadowSync* self, Particle_Index** globalParticlesOutsideDomainCountsPtr, Particle_Index* maxGlobalParticlesOutsideDomainCountPtr, Particle_Index* globalParticlesOutsideDomainTotalPtr ) { Processor_Index proc_I; (*globalParticlesOutsideDomainCountsPtr) = Memory_Alloc_Array( Particle_Index, self->swarm->nProc, "(*globalParticlesOutsideDomainCountsPtr)" ); (void)MPI_Allgather( (&self->particlesOutsideDomainTotalCount), 1, MPI_UNSIGNED, (*globalParticlesOutsideDomainCountsPtr), 1, MPI_UNSIGNED, self->swarm->comm ); (*globalParticlesOutsideDomainTotalPtr) = 0; for ( proc_I=0; proc_I < self->swarm->nProc; proc_I++ ) { (*globalParticlesOutsideDomainTotalPtr) += (*globalParticlesOutsideDomainCountsPtr)[proc_I]; if ( (*globalParticlesOutsideDomainCountsPtr)[proc_I] > (*maxGlobalParticlesOutsideDomainCountPtr) ) { (*maxGlobalParticlesOutsideDomainCountPtr) = (*globalParticlesOutsideDomainCountsPtr)[proc_I]; } } #if DEBUG if ( Stream_IsPrintableLevel( self->debug, 2 ) ) { Journal_DPrintf( self->debug, "Global counts of particles moving outside domains:\n" ); Journal_DPrintf( self->debug, "\tTotal: %d, Counts: [", (*globalParticlesOutsideDomainTotalPtr) ); for ( proc_I=0; proc_I < self->swarm->nProc; proc_I++ ) { Journal_DPrintf( self->debug, "%d, ", (*globalParticlesOutsideDomainCountsPtr)[proc_I] ); } Journal_DPrintf( self->debug, "]\n" ); } #endif }
void _Ppc_Switch_AssignFromXML( void* _self, Stg_ComponentFactory* cf, void* data ) { Ppc_Switch* self = (Ppc_Switch*)_self; Dictionary* theDictionary = NULL; Dictionary_Entry_Value* caseEntry = NULL; Dictionary_Entry_Value* tagList = NULL; Index case_I; char* ppcName; /* Construct parent */ _Ppc_AssignFromXML( self, cf, data ); /* The dictionary */ theDictionary = Dictionary_Entry_Value_AsDictionary( Dictionary_Get( cf->componentDict, (Dictionary_Entry_Key)self->name ) ); /* Read the properties list */ tagList = Dictionary_Get( theDictionary, (Dictionary_Entry_Key)"CaseList" ); assert( tagList ); self->caseCount = Dictionary_Entry_Value_GetCount( tagList ); self->caseList = Memory_Alloc_Array( Ppc_Switch_Case, self->caseCount, "Ppc_Switch_caseList" ); for( case_I = 0; case_I < self->caseCount; case_I++ ){ caseEntry = Dictionary_Entry_Value_GetElement( tagList, case_I ); /* get case value */ self->caseList[case_I].constant = Dictionary_Entry_Value_AsDouble( Dictionary_Entry_Value_GetMember( caseEntry, (Dictionary_Entry_Key)"Case") ); /* get ppc associated with the case*/ ppcName = Dictionary_Entry_Value_AsString( Dictionary_Entry_Value_GetMember( caseEntry, (Dictionary_Entry_Key)"Value") ); self->caseList[case_I].valueTag = PpcManager_GetPpcByName( self->manager, cf, (Name)ppcName ); } /* Init */ _Ppc_Switch_Init( self, Stg_ComponentFactory_GetString( cf, self->name, (Dictionary_Entry_Key)"Interpolate", "" ), PpcManager_GetPpcFromDict( self->manager, cf, self->name, (Dictionary_Entry_Key)"Field", "" ) ); }
void* _IndexMap_Copy( void* indexMap, void* dest, Bool deep, Name nameExt, struct PtrMap* ptrMap ) { IndexMap* self = (IndexMap*)indexMap; IndexMap* newIndexMap; PtrMap* map = ptrMap; Bool ownMap = False; if( !map ) { map = PtrMap_New( 10 ); ownMap = True; } newIndexMap = _Stg_Class_Copy( self, dest, deep, nameExt, map ); newIndexMap->dictionary = self->dictionary; newIndexMap->delta = self->delta; newIndexMap->maxTuples = self->maxTuples; newIndexMap->tupleCnt = self->tupleCnt; if( deep ) { if( (newIndexMap->tupleTbl = PtrMap_Find( map, self->tupleTbl )) == NULL && self->tupleTbl ) { newIndexMap->tupleTbl = Memory_Alloc_Array( IndexMapTuple, self->maxTuples, "IndexMap->tupleTbl" ); memcpy( newIndexMap->tupleTbl, self->tupleTbl, sizeof(IndexMapTuple) * self->maxTuples ); PtrMap_Append( map, self->tupleTbl, newIndexMap->tupleTbl ); } } else { newIndexMap->tupleTbl = self->tupleTbl; } if( ownMap ) { Stg_Class_Delete( map ); } return (void*)newIndexMap; }
void* _ConvexHull_Copy( void* convexHull, void* dest, Bool deep, Name nameExt, PtrMap* ptrMap ) { ConvexHull* self = (ConvexHull*)convexHull; ConvexHull* newConvexHull; newConvexHull = (ConvexHull*)_Stg_Shape_Copy( self, dest, deep, nameExt, ptrMap ); newConvexHull->vertexList = Memory_Alloc_Array( Coord, self->vertexCount, "vertexList" ); memcpy( newConvexHull->vertexList , self->vertexList, sizeof(Coord) * self->vertexCount ); newConvexHull->facesList = Memory_Alloc_Array( XYZ, self->vertexCount, "facesList" ); memcpy( newConvexHull->facesList, self->facesList, sizeof(XYZ) * self->vertexCount ); newConvexHull->vertexList = self->vertexList; newConvexHull->vertexCount = self->vertexCount; newConvexHull->facesList = self->facesList; return (void*)newConvexHull; }
void interpolateNode( void* _context, Node_LocalIndex newNodeInd, Element_DomainIndex dEltInd ) { Snac_Context* context = (Snac_Context*)_context; SnacRemesher_Context* contextExt = ExtensionManager_Get( context->extensionMgr, context, SnacRemesher_ContextHandle ); Mesh* mesh = context->mesh; SnacRemesher_Mesh* meshExt = ExtensionManager_Get( context->meshExtensionMgr, mesh, SnacRemesher_MeshHandle ); NodeLayout* nLayout = mesh->layout->nodeLayout; unsigned nEltNodes; Node_DomainIndex* eltNodes; Coord newNodeCoord; Coord crds[8]; double weights[4]; unsigned tetNodeInds[4]; unsigned eltNode_i; /* Extract the element's node indices. Note that there should always be eight of these. */ { Element_GlobalIndex gEltInd; nEltNodes = 8; eltNodes = Memory_Alloc_Array( Node_DomainIndex, nEltNodes, "SnacRemesher" ); gEltInd = Mesh_ElementMapDomainToGlobal( mesh, dEltInd ); nLayout->buildElementNodes( nLayout, gEltInd, eltNodes ); } /* Convert global node indices to domain. */ { unsigned eltNode_i; for( eltNode_i = 0; eltNode_i < nEltNodes; eltNode_i++ ) { eltNodes[eltNode_i] = Mesh_NodeMapGlobalToDomain( mesh, eltNodes[eltNode_i] ); } } /* Extract the new node's coordinate. */ Vector_Set( newNodeCoord, meshExt->newNodeCoords[newNodeInd] ); /* Copy coordinates. */ for( eltNode_i = 0; eltNode_i < nEltNodes; eltNode_i++ ) memcpy( crds[eltNode_i], mesh->nodeCoord[eltNodes[eltNode_i]], sizeof(Coord) ); if( !_HexaEL_FindTetBarycenter( crds, newNodeCoord, weights, tetNodeInds, INCLUSIVE_UPPER_BOUNDARY, NULL, 0 ) ) abort(); SnacRemesher_InterpolateNode( context, contextExt, newNodeInd, dEltInd, 0, tetNodeInds, weights, meshExt->newNodes ); /* Free the element node array. */ FreeArray( eltNodes ); }
void* _Stg_ObjectList_Copy( void* namedObjectList, void* dest, Bool deep, Name nameExt, struct PtrMap* ptrMap ) { Stg_ObjectList* self = (Stg_ObjectList*) namedObjectList; Stg_ObjectList* newObjectList; newObjectList = (Stg_ObjectList*)_Stg_Class_Copy( self, dest, deep, nameExt, ptrMap ); newObjectList->_append = self->_append; newObjectList->_prepend = self->_prepend; newObjectList->_append = self->_append; newObjectList->_replaceAll = self->_replaceAll; newObjectList->_replace = self->_replace; newObjectList->_insertBefore = self->_insertBefore; newObjectList->_insertAfter = self->_insertAfter; newObjectList->_remove = self->_remove; newObjectList->_getIndex = self->_getIndex; newObjectList->_get = self->_get; newObjectList->_allocMoreMemory = self->_allocMoreMemory; newObjectList->_insertAtIndex = self->_insertAtIndex; newObjectList->_removeByIndex = self->_removeByIndex; newObjectList->_deleteAllObjects = self->_deleteAllObjects; newObjectList->count = self->count; newObjectList->_size = self->_size; newObjectList->_delta = self->_delta; newObjectList->_noJournalingInCopy = self->_noJournalingInCopy; /* * As this class is used by the Journal backend, making Journal calls when used in the Journal backend, * is problematic... in this case work around it. It seems to only be an issue for copying. */ if( self->_noJournalingInCopy ) { assert( deep ); } else { Journal_Firewall( deep, Journal_Register( Error_Type, Stg_ObjectList_Type ), "Shallow copy not yet implemented\n"); } if( deep ) { unsigned obj_I; newObjectList->data = (Stg_ObjectPtr*)Memory_Alloc_Array( Stg_ObjectPtr, newObjectList->_size, "ObjectList->data" ); for( obj_I = 0; obj_I < newObjectList->count; obj_I++ ) { newObjectList->data[obj_I] = (Stg_ObjectPtr)Stg_Class_Copy( self->data[obj_I], NULL, deep, nameExt, ptrMap ); } } return newObjectList; }
void TestSuite_SetTests( void* testSuite, unsigned nTests, TestSuite_Test* tests ) { TestSuite* self = (TestSuite*)testSuite; assert( self ); assert( !nTests || tests ); TestSuite_Destruct( self ); self->nTests = nTests; if( nTests ) { self->tests = Memory_Alloc_Array( TestSuite_Test, nTests, "TestSuite::tests" ); memcpy( self->tests, tests, nTests * sizeof(TestSuite_Test) ); } }
void _PeriodicBoundariesManager_Build( void* periodicBCsManager, void* data ) { PeriodicBoundariesManager* self = (PeriodicBoundariesManager*)periodicBCsManager; Dictionary_Entry_Value* periodicBCsList = NULL; Stg_Component_Build( self->swarm, data, False ); Stg_Component_Build( self->mesh, data, False ); self->size = 4; self->boundaries = Memory_Alloc_Array( PeriodicBoundary, self->size, "PeriodicBoundariesManager->boundaries" ); if ( self->dictionary ) { periodicBCsList = Dictionary_Get( self->dictionary, (Dictionary_Entry_Key)"PeriodicBoundaries" ); /* Dictionary entry is optional - users may prefer to enter in code */ if ( periodicBCsList ) { Index numPeriodicBCs = 0; Index periodicBC_I = 0; Dictionary_Entry_Value* periodicBC = NULL; char* perBCAxis = NULL; numPeriodicBCs = Dictionary_Entry_Value_GetCount( periodicBCsList ); for ( periodicBC_I = 0; periodicBC_I < numPeriodicBCs; periodicBC_I++ ) { periodicBC = Dictionary_Entry_Value_GetElement( periodicBCsList, periodicBC_I ); perBCAxis = Dictionary_Entry_Value_AsString( periodicBC ); if ( 0 == strcmp( perBCAxis, "I_AXIS" ) ) { PeriodicBoundariesManager_AddPeriodicBoundary( self, I_AXIS ); } else if ( 0 == strcmp( perBCAxis, "J_AXIS" ) ) { PeriodicBoundariesManager_AddPeriodicBoundary( self, J_AXIS ); } else if ( 0 == strcmp( perBCAxis, "K_AXIS" ) ) { PeriodicBoundariesManager_AddPeriodicBoundary( self, K_AXIS ); } } } } /* Test if mesh is periodic */ else if ( Stg_Class_IsInstance( self->mesh->generator, CartesianGenerator_Type ) ) { CartesianGenerator* cartesianGenerator = (CartesianGenerator*) self->mesh->generator; Dimension_Index dim_I; for ( dim_I = 0 ; dim_I < self->swarm->dim ; dim_I++ ) { /* Add boundaries straight from mesh generator */ if ( cartesianGenerator->periodic[ dim_I ] ) PeriodicBoundariesManager_AddPeriodicBoundary( self, dim_I ); } } }
void _IndexMap_Init( IndexMap* self, unsigned delta ) { /* General and Virtual info should already be set */ /* IndexMap info */ assert( self ); self->delta = delta; self->maxTuples = self->delta; self->tupleTbl = Memory_Alloc_Array( IndexMapTuple, self->maxTuples, "IndexMap->tupleTbl" ); assert( self->tupleTbl ); /* TODO change this to a firewall, or something */ self->tupleCnt = 0; }
void _lucIsosurface_Init( lucIsosurface* self, double isovalue, IJK resolution, Bool drawWalls, Bool sampleGlobal, lucDrawingObjectMask* mask ) { self->isovalue = isovalue; memcpy( self->resolution, resolution, sizeof(IJK) ); self->drawWalls = drawWalls; self->sampleGlobal = sampleGlobal; memcpy( &self->mask, mask, sizeof(lucDrawingObjectMask) ); self->trianglesAlloced = 100; self->triangleList = Memory_Alloc_Array( Surface_Triangle, self->trianglesAlloced, "triangleList" ); }
void _ConvexHull_AssignFromXML( void* convexHull, Stg_ComponentFactory* cf, void* data ) { ConvexHull* self = (ConvexHull*)convexHull; Index vertexCount; Index vertex_I; Coord_List vertexList; double* coord; Dictionary_Entry_Value* optionSet; Dictionary_Entry_Value* optionsList; Dictionary* dictionary = Dictionary_GetDictionary( cf->componentDict, self->name ); Stream* stream = cf->infoStream; _Stg_Shape_AssignFromXML( self, cf, data ); optionsList = Dictionary_Get( dictionary, (Dictionary_Entry_Key)"vertices" ); Journal_Firewall( optionsList != NULL, Journal_Register( Error_Type, (Name)self->type ), "In func %s: The list 'vertices' specifying the convexHull is NULL.\n", __func__); vertexCount = Dictionary_Entry_Value_GetCount(optionsList); Journal_Firewall( ( self->dim == 2 && vertexCount < 4 ) || ( self->dim == 3 && vertexCount < 5 ), Journal_Register( Error_Type, (Name)self->type ), "In func %s: Sorry, but we got lazy, you can only specify 3 (2D) or 4 (3D) points. " "Please feel free to hassle developers for this feature.\n", __func__); /* Allocate space */ vertexList = Memory_Alloc_Array( Coord , vertexCount, "Vertex Array" ); memset( vertexList, 0, vertexCount * sizeof(Coord) ); Stream_Indent( stream ); for ( vertex_I = 0 ; vertex_I < vertexCount ; vertex_I++) { optionSet = Dictionary_Entry_Value_GetElement(optionsList, vertex_I ); coord = vertexList[vertex_I]; /* Read Vertex */ coord[ I_AXIS ] = Dictionary_Entry_Value_AsDouble( Dictionary_Entry_Value_GetMember( optionSet, (Dictionary_Entry_Key)"x") ); coord[ J_AXIS ] = Dictionary_Entry_Value_AsDouble( Dictionary_Entry_Value_GetMember( optionSet, (Dictionary_Entry_Key)"y") ); coord[ K_AXIS ] = Dictionary_Entry_Value_AsDouble( Dictionary_Entry_Value_GetMember( optionSet, (Dictionary_Entry_Key)"z")); optionSet = optionSet->next; } Stream_UnIndent( stream ); _ConvexHull_Init( self, vertexList, vertexCount); }
void* _SingleCellLayout_Copy( void* singleCellLayout, void* dest, Bool deep, Name nameExt, PtrMap* ptrMap ) { SingleCellLayout* self = (SingleCellLayout*)singleCellLayout; SingleCellLayout* newSingleCellLayout; PtrMap* map = ptrMap; Bool ownMap = False; if( !map ) { map = PtrMap_New( 10 ); ownMap = True; } newSingleCellLayout = _CellLayout_Copy( self, dest, deep, nameExt, ptrMap ); newSingleCellLayout->dimExists[0] = self->dimExists[0]; newSingleCellLayout->dimExists[1] = self->dimExists[1]; newSingleCellLayout->dimExists[2] = self->dimExists[2]; newSingleCellLayout->min[0] = self->min[0]; newSingleCellLayout->min[1] = self->min[1]; newSingleCellLayout->min[2] = self->min[2]; newSingleCellLayout->max[0] = self->max[0]; newSingleCellLayout->max[1] = self->max[1]; newSingleCellLayout->max[2] = self->max[2]; newSingleCellLayout->pointCount = self->pointCount; if( deep ) { if( (newSingleCellLayout->cellPointCoords = PtrMap_Find( map, self->cellPointCoords )) == NULL && self->cellPointCoords ) { newSingleCellLayout->cellPointCoords = Memory_Alloc_Array( Coord, newSingleCellLayout->pointCount, "SingleCellLayout->cellPoints" ); memcpy( newSingleCellLayout->cellPointCoords, self->cellPointCoords, sizeof(Coord) * newSingleCellLayout->pointCount ); PtrMap_Append( map, self->cellPointCoords, newSingleCellLayout->cellPointCoords ); } } else { newSingleCellLayout->cellPointCoords = self->cellPointCoords; } if( ownMap ) { Stg_Class_Delete( map ); } return (void*)newSingleCellLayout; }
void* _PeriodicBoundariesManager_Copy( void* periodicBCsManager, void* dest, Bool deep, Name nameExt, PtrMap* ptrMap ) { PeriodicBoundariesManager* self = (PeriodicBoundariesManager*)periodicBCsManager; PeriodicBoundariesManager* newPeriodicBCsManager; PtrMap* map = ptrMap; Bool ownMap = False; if( !map ) { map = PtrMap_New( 10 ); ownMap = True; } newPeriodicBCsManager = _Stg_Class_Copy( self, dest, deep, nameExt, map ); newPeriodicBCsManager->count = self->count; newPeriodicBCsManager->size = self->size; newPeriodicBCsManager->delta = self->delta; if ( deep ) { newPeriodicBCsManager->dictionary = (Dictionary*)Stg_Class_Copy( self->dictionary, NULL, deep, nameExt, map ); newPeriodicBCsManager->mesh = (Mesh*)Stg_Class_Copy( self->mesh, NULL, deep, nameExt, map ); newPeriodicBCsManager->swarm = (Swarm*)Stg_Class_Copy( self->swarm, NULL, deep, nameExt, map ); newPeriodicBCsManager->debug = self->debug; newPeriodicBCsManager->boundaries = Memory_Alloc_Array( PeriodicBoundary, self->size, "PeriodicBoundaries" ); memcpy( newPeriodicBCsManager->boundaries, self->boundaries, sizeof(PeriodicBoundary)*self->count ); } else { newPeriodicBCsManager->dictionary = self->dictionary; newPeriodicBCsManager->mesh = self->mesh; newPeriodicBCsManager->swarm = self->swarm; newPeriodicBCsManager->boundaries = self->boundaries; newPeriodicBCsManager->debug = self->debug; } if( ownMap ) { Stg_Class_Delete( map ); } return (void*)newPeriodicBCsManager; }
/*---------------------------------------------------------------------------------------------------------- ** Virtual functions */ void _LinearSpaceAdaptor_AssignFromXML( void* _self, Stg_ComponentFactory* cf, void* data ) { LinearSpaceAdaptor* self = (LinearSpaceAdaptor*)_self; Dictionary* dictionary = Dictionary_GetDictionary( cf->componentDict, self->name ); Dictionary_Entry_Value* optionsList = NULL; Dictionary_Entry_Value* optionSet = NULL; linearSpaceAdaptor_Segment* seg = NULL; Index segmentCount; Index segment_I; AbstractContext* context; assert( self ); assert( cf ); /* Call parent construct. */ _MeshAdaptor_AssignFromXML( self, cf, data ); context = (AbstractContext*)Stg_ComponentFactory_ConstructByKey( cf, self->name, (Dictionary_Entry_Key)"Context", AbstractContext, False, data ); if( !context ) context = Stg_ComponentFactory_ConstructByName( cf, (Name)"context", AbstractContext, True, data ); self->loadFromCheckPoint = context->loadFromCheckPoint; if( self->loadFromCheckPoint ) return; self->minX = Dictionary_Entry_Value_AsDouble( Dictionary_Get( cf->rootDict, (Dictionary_Entry_Key)"minX" ) ); self->maxX = Dictionary_Entry_Value_AsDouble( Dictionary_Get( cf->rootDict, (Dictionary_Entry_Key)"maxX" ) ); self->minY = Dictionary_Entry_Value_AsDouble( Dictionary_Get( cf->rootDict, (Dictionary_Entry_Key)"minY" ) ); self->maxY = Dictionary_Entry_Value_AsDouble( Dictionary_Get( cf->rootDict, (Dictionary_Entry_Key)"maxY" ) ); self->minZ = Dictionary_Entry_Value_AsDouble( Dictionary_Get( cf->rootDict, (Dictionary_Entry_Key)"minZ" ) ); self->maxZ = Dictionary_Entry_Value_AsDouble( Dictionary_Get( cf->rootDict, (Dictionary_Entry_Key)"maxZ" ) ); /* Read mapping functions - X axis*/ optionsList = Dictionary_Get( dictionary, (Dictionary_Entry_Key)"mappingFunctionX" ); if( optionsList ) { segmentCount = Dictionary_Entry_Value_GetCount(optionsList ); self->nSegmentsx = segmentCount; self->tablex = Memory_Alloc_Array( linearSpaceAdaptor_Segment , segmentCount, "mapping table x" ); memset( self->tablex, 0, segmentCount * sizeof(linearSpaceAdaptor_Segment) ); for ( segment_I = 0 ; segment_I < segmentCount ; segment_I++) { optionSet = Dictionary_Entry_Value_GetElement(optionsList, segment_I ); seg = &(self->tablex[segment_I]); seg->x = Dictionary_Entry_Value_AsDouble( Dictionary_Entry_Value_GetMember( optionSet, (Dictionary_Entry_Key)"point" ) ); seg->y = Dictionary_Entry_Value_AsDouble( Dictionary_Entry_Value_GetMember( optionSet, (Dictionary_Entry_Key)"mappedTo" ) ); } } else { self->nSegmentsx = 0; } /* Read mapping functions - Y axis*/ optionsList = Dictionary_Get( dictionary, (Dictionary_Entry_Key)"mappingFunctionY" ); if( optionsList ) { segmentCount = Dictionary_Entry_Value_GetCount(optionsList ); self->nSegmentsy = segmentCount; self->tabley = Memory_Alloc_Array( linearSpaceAdaptor_Segment , segmentCount, "mapping table y" ); memset( self->tabley, 0, segmentCount * sizeof(linearSpaceAdaptor_Segment) ); for ( segment_I = 0; segment_I < segmentCount; segment_I++) { optionSet = Dictionary_Entry_Value_GetElement(optionsList, segment_I ); seg = &(self->tabley[segment_I]); seg->x = Dictionary_Entry_Value_AsDouble( Dictionary_Entry_Value_GetMember( optionSet, (Dictionary_Entry_Key)"point" ) ); seg->y = Dictionary_Entry_Value_AsDouble( Dictionary_Entry_Value_GetMember( optionSet, (Dictionary_Entry_Key)"mappedTo" ) ); } } else { self->nSegmentsy = 0; } /* Read mapping functions - Z axis*/ optionsList = Dictionary_Get( dictionary, (Dictionary_Entry_Key)"mappingFunctionZ" ); if( optionsList && ((DomainContext*)context)->dim==3 ) { segmentCount = Dictionary_Entry_Value_GetCount(optionsList ); self->nSegmentsz = segmentCount; self->tablez = Memory_Alloc_Array( linearSpaceAdaptor_Segment , segmentCount, "mapping table z" ); memset( self->tablez, 0, segmentCount * sizeof(linearSpaceAdaptor_Segment) ); for ( segment_I = 0 ; segment_I < segmentCount ; segment_I++) { optionSet = Dictionary_Entry_Value_GetElement(optionsList, segment_I ); seg = &(self->tablez[segment_I]); seg->x = Dictionary_Entry_Value_AsDouble( Dictionary_Entry_Value_GetMember( optionSet, (Dictionary_Entry_Key)"point" ) ); seg->y = Dictionary_Entry_Value_AsDouble( Dictionary_Entry_Value_GetMember( optionSet, (Dictionary_Entry_Key)"mappedTo" ) ); } } else { self->nSegmentsz = 0; } _LinearSpaceAdaptor_Init( self ); }
int main(int argc, char **argv) { MPI_Comm CommWorld; XML_IO_Handler *io_handler = XML_IO_Handler_New(); int rank, procCount, procToWatch; Dictionary *dictionary; EmbeddedSurface *surface; MeshTopology *rmt, *imt; MeshGeometry *rmg, *img; MeshDecomp *rmd, *imd; MeshLayout *rml, *isl; ExtensionManager_Register *extensionMgr_Register; Mesh *mesh; Element_GlobalIndex intersectCnt, *intersect; Index i; /* Initialise MPI, get world info */ MPI_Init( &argc, &argv ); MPI_Comm_dup( MPI_COMM_WORLD, &CommWorld ); MPI_Comm_size( CommWorld, &procCount ); MPI_Comm_rank( CommWorld, &rank ); Base_Init( &argc, &argv ); DiscretisationGeometry_Init( &argc, &argv ); DiscretisationShape_Init( &argc, &argv ); DiscretisationMesh_Init( &argc, &argv ); DiscretisationUtils_Init( &argc, &argv ); MPI_Barrier( CommWorld ); /* Ensures copyright info always come first in output */ if( argc >= 2 ) procToWatch = atoi( argv[1] ); else procToWatch = 0; if( rank == procToWatch ) printf( "Watching rank: %i\n", rank ); dictionary = Dictionary_New(); Dictionary_Add( dictionary, "rank", Dictionary_Entry_Value_FromUnsignedInt( rank ) ); Dictionary_Add( dictionary, "numProcessors", Dictionary_Entry_Value_FromUnsignedInt( procCount ) ); Dictionary_Add( dictionary, "meshSizeI", Dictionary_Entry_Value_FromUnsignedInt( 2 ) ); Dictionary_Add( dictionary, "meshSizeJ", Dictionary_Entry_Value_FromUnsignedInt( 2 ) ); Dictionary_Add( dictionary, "meshSizeK", Dictionary_Entry_Value_FromUnsignedInt( 4 ) ); Dictionary_Add( dictionary, "allowUnusedCPUs", Dictionary_Entry_Value_FromBool( True ) ); Dictionary_Add( dictionary, "allowPartitionOnElement", Dictionary_Entry_Value_FromBool( True ) ); Dictionary_Add( dictionary, "allowPartitionOnNode", Dictionary_Entry_Value_FromBool( True ) ); Dictionary_Add( dictionary, "shadowDepth", Dictionary_Entry_Value_FromUnsignedInt( 0 ) ); IO_Handler_ReadAllFromFile(io_handler, "data/surface.xml", dictionary); rmt = (MeshTopology *)HexaMeshTopology_New(dictionary); rmg = (MeshGeometry *)HexaMeshGeometry_New(dictionary); rmd = (MeshDecomp *)HexaMeshDecomp_New(dictionary, MPI_COMM_WORLD, (HexaMeshTopology *)rmt); rml = MeshLayout_New(dictionary, rmt, rmg, rmd); imt = (MeshTopology *)TriSurfTopology_New(dictionary, "imElements"); img = (MeshGeometry *)TriSurfGeometry_New(dictionary, "imNodes"); imd = (MeshDecomp *)IrregularMeshDecomp_New1(dictionary, MPI_COMM_WORLD, imt, img, rml); isl = MeshLayout_New(dictionary, imt, img, imd); extensionMgr_Register = ExtensionManager_Register_New( ); mesh = Mesh_New( isl, sizeof(Node), sizeof(Element), extensionMgr_Register, dictionary ); Mesh_Build( mesh ); Mesh_Initialise(mesh); surface = EmbeddedSurface_New(mesh); if (procToWatch == rank) { intersect = Memory_Alloc_Array( Element_GlobalIndex, isl->decomp->elementGlobalCount(isl->decomp), "intersect" ); intersectCnt = EmbeddedSurface_BuildIntersection(surface, intersect); printf("Intersects: %u\n", intersectCnt); for (i = 0; i < intersectCnt; i++) printf("\tinstersect[%u]: %u\n", i, intersect[i]); printf("\n"); if (intersect) Memory_Free(intersect); for (i = 0; i < isl->decomp->nodeGlobalCount(isl->decomp); i++) { Coord point; point[0] = ((TriSurfGeometry *)img)->node[i][0] + 1.0; point[1] = ((TriSurfGeometry *)img)->node[i][1]; point[2] = ((TriSurfGeometry *)img)->node[i][2]; printf("Distance to point {%.3f, %.3f, %.3f}: ", point[0], point[1], point[2]); printf("%.3f\n", EmbeddedSurface_DistanceToPoint(surface, point)); } } Stg_Class_Delete(surface); Stg_Class_Delete(isl); Stg_Class_Delete(imd); Stg_Class_Delete(img); Stg_Class_Delete(imt); Stg_Class_Delete(rml); Stg_Class_Delete(rmd); Stg_Class_Delete(rmg); Stg_Class_Delete(rmt); DiscretisationUtils_Finalise(); DiscretisationMesh_Finalise(); DiscretisationShape_Finalise(); DiscretisationGeometry_Finalise(); Base_Finalise(); /* Close off MPI */ MPI_Finalize(); return 0; }
int main( int argc, char* argv[] ) { MPI_Comm CommWorld; int rank; int procCount; Dictionary* dictionary; Geometry* geometry; ElementLayout* eLayout; Topology* nTopology; NodeLayout* nLayout; HexaMD* meshDecomp; Element_GlobalIndex e_I; Index i; /* Initialise MPI, get world info */ MPI_Init(&argc, &argv); MPI_Comm_dup( MPI_COMM_WORLD, &CommWorld ); MPI_Comm_size(CommWorld, &procCount); MPI_Comm_rank(CommWorld, &rank); Base_Init( &argc, &argv ); DiscretisationGeometry_Init( &argc, &argv ); DiscretisationShape_Init( &argc, &argv ); DiscretisationMesh_Init( &argc, &argv ); MPI_Barrier( CommWorld ); /* Ensures copyright info always come first in output */ dictionary = Dictionary_New(); Dictionary_Add( dictionary, "meshSizeI", Dictionary_Entry_Value_FromUnsignedInt( 4 ) ); Dictionary_Add( dictionary, "meshSizeJ", Dictionary_Entry_Value_FromUnsignedInt( 4 ) ); Dictionary_Add( dictionary, "meshSizeK", Dictionary_Entry_Value_FromUnsignedInt( 4 ) ); geometry = (Geometry*)BlockGeometry_New( "blockGeometry", dictionary ); eLayout = (ElementLayout*)HexaEL_New( "HexaEL", 3, dictionary, geometry ); nTopology = (Topology*)IJK6Topology_New( "IJK6Topology", dictionary ); nLayout = (NodeLayout*)CornerNL_New( "CornerNL", dictionary, eLayout, nTopology ); meshDecomp = HexaMD_New( "HexaMD", dictionary, MPI_COMM_WORLD, eLayout, nLayout ); ElementLayout_Build( eLayout, meshDecomp ); printf( "Element corner indices:\n" ); for( e_I = 0; e_I < eLayout->elementCount; e_I++ ) { Index* corners = Memory_Alloc_Array( Index, eLayout->elementCornerCount, "corners" ); eLayout->buildCornerIndices( eLayout, e_I, corners ); printf( "\tElement %u : { %u", e_I, corners[0] ); for( i = 1; i < eLayout->elementCornerCount; i++ ) printf( ", %u", corners[i] ); printf( " }\n" ); } printf( "\n" ); printf( "Corner element indices:\n" ); for( i = 0; i < eLayout->cornerCount; i++ ) { Element_GlobalIndex elementCnt = eLayout->cornerElementCount( eLayout, i ); Element_GlobalIndex* elements = Memory_Alloc_Array( Element_GlobalIndex, elementCnt, "elements" ); eLayout->buildCornerElements( eLayout, i, elements ); printf( "\tCorner %u : { %u", i, elements[0] ); for( e_I = 1; e_I < elementCnt; e_I++ ) printf( ", %u", elements[e_I] ); printf( " }\n" ); } printf( "\n" ); printf( "Element with point:\n" ); for( i = 0; i < geometry->pointCount; i++ ) { Coord point; geometry->pointAt( geometry, i, point ); point[0] += 0.1; point[1] += 0.1; point[2] += 0.1; printf( "\tPoint %u : %u\n", i, eLayout->elementWithPoint( eLayout, meshDecomp, point, NULL, EXCLUSIVE_UPPER_BOUNDARY, 0, NULL ) ); } printf( "\n" ); Stg_Class_Delete( dictionary ); Stg_Class_Delete( meshDecomp ); Stg_Class_Delete( nLayout ); Stg_Class_Delete( nTopology ); Stg_Class_Delete( eLayout ); Stg_Class_Delete( geometry ); DiscretisationMesh_Finalise(); DiscretisationShape_Finalise(); DiscretisationGeometry_Finalise(); Base_Finalise(); /* Close off MPI */ MPI_Finalize(); return 0; }
void _FrictionVC_ReadDictionary( void* variableCondition, void* dictionary ) { FrictionVC* self = (FrictionVC*)variableCondition; Dictionary_Entry_Value* vcDictVal; Dictionary_Entry_Value _vcDictVal; Dictionary_Entry_Value* varsVal; FrictionVC_Entry_Index entry_I; /* Find dictionary entry */ if (self->_dictionaryEntryName) vcDictVal = Dictionary_Get(dictionary, self->_dictionaryEntryName); else { vcDictVal = &_vcDictVal; Dictionary_Entry_Value_InitFromStruct(vcDictVal, dictionary); } if (vcDictVal) { char* wallStr; /* Obtain which wall */ wallStr = Dictionary_Entry_Value_AsString(Dictionary_Entry_Value_GetMember(vcDictVal, "wall" )); if (!strcasecmp(wallStr, "back")) self->_wall = FrictionVC_Wall_Back; else if (!strcasecmp(wallStr, "left")) self->_wall = FrictionVC_Wall_Left; else if (!strcasecmp(wallStr, "bottom")) self->_wall = FrictionVC_Wall_Bottom; else if (!strcasecmp(wallStr, "right")) self->_wall = FrictionVC_Wall_Right; else if (!strcasecmp(wallStr, "top")) self->_wall = FrictionVC_Wall_Top; else if (!strcasecmp(wallStr, "front")) self->_wall = FrictionVC_Wall_Front; else { assert( 0 ); self->_wall = FrictionVC_Wall_Size; /* invalid entry */ } /* Obtain the variable entries */ self->_entryCount = 0; self->_entryCount = Dictionary_Entry_Value_GetCount(Dictionary_Entry_Value_GetMember(vcDictVal, "variables")); self->_entryTbl = Memory_Alloc_Array( FrictionVC_Entry, self->_entryCount, "FrictionVC->_entryTbl" ); varsVal = Dictionary_Entry_Value_GetMember(vcDictVal, "variables"); for (entry_I = 0; entry_I < self->_entryCount; entry_I++) { char* valType; Dictionary_Entry_Value* valueEntry; Dictionary_Entry_Value* varDictListVal; varDictListVal = Dictionary_Entry_Value_GetElement(varsVal, entry_I); valueEntry = Dictionary_Entry_Value_GetMember(varDictListVal, "value"); self->_entryTbl[entry_I].varName = Dictionary_Entry_Value_AsString( Dictionary_Entry_Value_GetMember(varDictListVal, "name")); valType = Dictionary_Entry_Value_AsString(Dictionary_Entry_Value_GetMember(varDictListVal, "type")); if (0 == strcasecmp(valType, "func")) { char* funcName = Dictionary_Entry_Value_AsString(valueEntry); Index cfIndex; self->_entryTbl[entry_I].value.type = VC_ValueType_CFIndex; cfIndex = ConditionFunction_Register_GetIndex( self->conFunc_Register, funcName); if ( cfIndex == (unsigned)-1 ) { Stream* errorStr = Journal_Register( Error_Type, self->type ); Journal_Printf( errorStr, "Error- in %s: While parsing " "definition of wallVC \"%s\" (applies to wall \"%s\"), the cond. func. applied to " "variable \"%s\" - \"%s\" - wasn't found in the c.f. register.\n", __func__, self->_dictionaryEntryName, FrictionVC_WallEnumToStr[self->_wall], self->_entryTbl[entry_I].varName, funcName ); Journal_Printf( errorStr, "(Available functions in the C.F. register are: "); ConditionFunction_Register_PrintNameOfEachFunc( self->conFunc_Register, errorStr ); Journal_Printf( errorStr, ")\n"); assert(0); } self->_entryTbl[entry_I].value.as.typeCFIndex = cfIndex; } else if (0 == strcasecmp(valType, "array")) { Dictionary_Entry_Value* valueElement; Index i; self->_entryTbl[entry_I].value.type = VC_ValueType_DoubleArray; self->_entryTbl[entry_I].value.as.typeArray.size = Dictionary_Entry_Value_GetCount(valueEntry); self->_entryTbl[entry_I].value.as.typeArray.array = Memory_Alloc_Array( double, self->_entryTbl[entry_I].value.as.typeArray.size, "FrictionVC->_entryTbl[].value.as.typeArray.array" ); for (i = 0; i < self->_entryTbl[entry_I].value.as.typeArray.size; i++) { valueElement = Dictionary_Entry_Value_GetElement(valueEntry, i); self->_entryTbl[entry_I].value.as.typeArray.array[i] = Dictionary_Entry_Value_AsDouble(valueElement); } } else if( 0 == strcasecmp( valType, "double" ) || 0 == strcasecmp( valType, "d" ) || 0 == strcasecmp( valType, "float" ) || 0 == strcasecmp( valType, "f" ) ) { self->_entryTbl[entry_I].value.type = VC_ValueType_Double; self->_entryTbl[entry_I].value.as.typeDouble = Dictionary_Entry_Value_AsDouble( valueEntry ); } else if( 0 == strcasecmp( valType, "integer" ) || 0 == strcasecmp( valType, "int" ) || 0 == strcasecmp( valType, "i" ) ) { self->_entryTbl[entry_I].value.type = VC_ValueType_Int; self->_entryTbl[entry_I].value.as.typeInt = Dictionary_Entry_Value_AsUnsignedInt( valueEntry ); } else if( 0 == strcasecmp( valType, "short" ) || 0 == strcasecmp( valType, "s" ) ) { self->_entryTbl[entry_I].value.type = VC_ValueType_Short; self->_entryTbl[entry_I].value.as.typeShort = Dictionary_Entry_Value_AsUnsignedInt( valueEntry ); } else if( 0 == strcasecmp( valType, "char" ) || 0 == strcasecmp( valType, "c" ) ) { self->_entryTbl[entry_I].value.type = VC_ValueType_Char; self->_entryTbl[entry_I].value.as.typeChar = Dictionary_Entry_Value_AsUnsignedInt( valueEntry ); } else if( 0 == strcasecmp( valType, "pointer" ) || 0 == strcasecmp( valType, "ptr" ) || 0 == strcasecmp( valType, "p" ) ) { self->_entryTbl[entry_I].value.type = VC_ValueType_Ptr; self->_entryTbl[entry_I].value.as.typePtr = (void*) ( (ArithPointer)Dictionary_Entry_Value_AsUnsignedInt( valueEntry )); } else { /* Assume double */ Journal_DPrintf( Journal_Register( InfoStream_Type, "myStream" ), "Type to variable on variable condition not given, assuming double\n" ); self->_entryTbl[entry_I].value.type = VC_ValueType_Double; self->_entryTbl[entry_I].value.as.typeDouble = Dictionary_Entry_Value_AsDouble( valueEntry ); } }
Particle_Index* ParticleMovementHandler_MergeListsOfUnfilledParticleSlots( ParticleCommHandler* self ) { Particle_Index* mergedLeavingParticleArray = NULL; Particle_Index slotsToFillTotalCount = 0; Index currMergedLeavingParticleEntry = 0; Index lowestUnmergedLeavingViaShadow = self->currShadowParticleLeavingMeIndex; Index lowestUnmergedLeavingDomain = self->currParticleLeavingMyDomainIndex; Particle_Index indexOfLowestUnmergedLeavingDomain = 0; Index* lowestUnmergedLeavingEntryToUpdatePtr = NULL; Particle_Index candidateMergeParticle = 0; Journal_DPrintfL( self->debug, 1, "In %s():\n", __func__ ); Stream_Indent( self->debug ); slotsToFillTotalCount = self->particlesOutsideDomainUnfilledCount + self->shadowParticlesLeavingMeUnfilledCount; mergedLeavingParticleArray = Memory_Alloc_Array( Particle_Index, slotsToFillTotalCount, "mergedLeavingParticlesArray" ); while ( currMergedLeavingParticleEntry < slotsToFillTotalCount ) { /* Need to initialise this to the max particle count every loop, in case the first condition is false, so the 2nd will always hit it. */ candidateMergeParticle = self->swarm->particleLocalCount; if ( lowestUnmergedLeavingViaShadow < self->shadowParticlesLeavingMeTotalCount ) { candidateMergeParticle = self->shadowParticlesLeavingMeIndices[lowestUnmergedLeavingViaShadow]; lowestUnmergedLeavingEntryToUpdatePtr = &lowestUnmergedLeavingViaShadow; } if ( lowestUnmergedLeavingDomain < self->particlesOutsideDomainTotalCount ) { indexOfLowestUnmergedLeavingDomain = self->particlesOutsideDomainIndices[lowestUnmergedLeavingDomain]; if ( indexOfLowestUnmergedLeavingDomain < candidateMergeParticle ) { candidateMergeParticle = indexOfLowestUnmergedLeavingDomain; lowestUnmergedLeavingEntryToUpdatePtr = &lowestUnmergedLeavingDomain; } } mergedLeavingParticleArray[currMergedLeavingParticleEntry++] = candidateMergeParticle; (*lowestUnmergedLeavingEntryToUpdatePtr)++; #if DEBUG Journal_Firewall( lowestUnmergedLeavingViaShadow <= self->shadowParticlesLeavingMeTotalCount, Swarm_Error, "Error: merging of unfilled particle lists stuffed up.\n" ); Journal_Firewall( lowestUnmergedLeavingDomain <= self->particlesOutsideDomainTotalCount, Swarm_Error, "Error: merging of unfilled particle lists stuffed up.\n" ); #endif } #if DEBUG if ( Stream_IsPrintableLevel( self->debug, 2 ) ) { Journal_DPrintf( self->debug, "Merged list of particles leaving proc:\n\t{" ); for ( currMergedLeavingParticleEntry=0; currMergedLeavingParticleEntry < slotsToFillTotalCount; currMergedLeavingParticleEntry++ ) { Journal_DPrintf( self->debug, "%d, ", mergedLeavingParticleArray[currMergedLeavingParticleEntry] ); } Journal_DPrintf( self->debug, "}\n" ); } #endif Stream_UnIndent( self->debug ); return mergedLeavingParticleArray; }
void ParticleMovementHandler_HandleParticleMovementBetweenProcs( ParticleCommHandler* pCommsHandler ) { ParticleMovementHandler* self = (ParticleMovementHandler*)pCommsHandler; double startTime = 0; Stream* info = Journal_Register( Info_Type, (Name)self->type ); Journal_DPrintfL( self->debug, 1, "In %s(), for swarm \"%s\":\n", __func__, self->swarm->name ); if ( 1 == self->swarm->nProc ) { Journal_DPrintfL( self->debug, 1, "Serial run -> nothing to communicate, returning.\n" ); Stream_UnIndentBranch( Swarm_Debug ); return; } Stream_IndentBranch( Swarm_Debug ); startTime = MPI_Wtime(); if ( self->swarm->cellShadowCount > 0 ) { /* Allocate the recv count arrays and handles */ self->allocateIncomingCountArrays( (ParticleCommHandler*)self ); self->allocateOutgoingCountArrays( (ParticleCommHandler*)self ); /* First thing to do is begin non-blocking receive of incoming particles (for latency hiding) */ self->beginReceiveOfIncomingParticleCounts( (ParticleCommHandler*)self ); /* Do a blocking send of outgoing counts, so our nbrs know what to receive */ self->sendOutgoingParticleCounts( (ParticleCommHandler*)self ); /* Now need to make sure that incoming particle counts are here, then begin receiving particles (We do this as early as possible for latency hiding purposes */ self->finishReceiveOfIncomingParticleCounts( (ParticleCommHandler*)self ); self->allocateIncomingParticleArrays( (ParticleCommHandler*)self ); self->beginReceiveOfIncomingParticles( (ParticleCommHandler*)self ); /* OK, now begin sending out particles we know need to go to nbrs */ self->allocateOutgoingParticleArrays( (ParticleCommHandler*)self ); self->beginSendingParticles( (ParticleCommHandler*)self ); } if ( self->useGlobalFallbackCommStrategy ) { self->particlesOutsideDomainIndices = Memory_Alloc_Array( Particle_Index, self->swarm->particlesArrayDelta, "self->particlesOutsideDomainIndices" ); ParticleMovementHandler_DoGlobalFallbackCommunication( self ); } if ( self->swarm->cellShadowCount > 0 ) { /* Ok, at this point make sure our non-blocking receive of incoming via domain boundary * particles have completed: then immediately insert these particles into our local swarm */ self->finishReceiveOfIncomingParticlesAndUpdateIndices( (ParticleCommHandler*)self ); } /* final update of the 'holes' in my particles list (some may be left if we sent more than we recv'd overall */ ParticleMovementHandler_FillRemainingHolesInLocalParticlesArray( (ParticleCommHandler*)self ); /* NB: Can't delete these until here, as they're needed by the "fillRemainingHoles" function above. */ if ( self->useGlobalFallbackCommStrategy ) { Memory_Free( self->particlesOutsideDomainIndices ); self->particlesOutsideDomainIndices = NULL; } if ( self->swarm->cellShadowCount > 0 ) { self->confirmOutgoingSendsCompleted( (ParticleCommHandler*)self ); } _ParticleCommHandler_PrintCommunicationVolumeStats( (ParticleCommHandler*)self, startTime, info ); MPI_Barrier( self->swarm->comm ); /* clean up allocated memory, and zero counters, ready for next timestep */ if ( self->swarm->cellShadowCount > 0 ) { self->freeIncomingArrays( (ParticleCommHandler*)self ); self->freeOutgoingArrays( (ParticleCommHandler*)self ); } _ParticleCommHandler_ZeroShadowCommStrategyCounters( (ParticleCommHandler*)self ); Stream_UnIndentBranch( Swarm_Debug ); }
void _SnacRemesher_InterpolateNodes( void* _context ) { Snac_Context* context = (Snac_Context*)_context; SnacRemesher_Context* contextExt = ExtensionManager_Get( context->extensionMgr, context, SnacRemesher_ContextHandle ); Mesh* mesh = context->mesh; SnacRemesher_Mesh* meshExt = ExtensionManager_Get( context->meshExtensionMgr, mesh, SnacRemesher_MeshHandle ); NodeLayout* nLayout = mesh->layout->nodeLayout; Node_LocalIndex newNode_i; IndexSet* extNodes; void interpolateNode( void* _context, Node_LocalIndex newNodeInd, Element_DomainIndex dEltInd ); /* ** Free any owned arrays that may still exist from the last node interpolation. */ FreeArray( meshExt->externalNodes ); meshExt->nExternalNodes = 0; /* ** Scoot over all the new nodes and find the old element in which each one resides, then interpolate. */ /* Create an index set for storing any external nodes. */ extNodes = IndexSet_New( mesh->nodeLocalCount ); for( newNode_i = 0; newNode_i < mesh->nodeLocalCount; newNode_i++ ) { Node_LocalIndex dNodeInd; unsigned nElements; Element_DomainIndex* elements; Coord newPoint; unsigned elt_i; /* Extract the new node's coordinate. */ Vector_Set( newPoint, meshExt->newNodeCoords[newNode_i] ); /* Find the closest old node. */ dNodeInd = findClosestNode( context, newPoint, newNode_i ); /* Grab incident elements. */ { Node_GlobalIndex gNodeInd; gNodeInd = Mesh_NodeMapDomainToGlobal( mesh, dNodeInd ); nElements = nLayout->nodeElementCount( nLayout, gNodeInd ); if( nElements ) { elements = Memory_Alloc_Array( Element_DomainIndex, nElements, "SnacRemesher" ); nLayout->buildNodeElements( nLayout, gNodeInd, elements ); } else { elements = NULL; } } /* Convert global element indices to domain. */ for( elt_i = 0; elt_i < nElements; elt_i++ ) { elements[elt_i] = Mesh_ElementMapGlobalToDomain( mesh, elements[elt_i] ); } /* Which of the incident elements contains the node? */ for( elt_i = 0; elt_i < nElements; elt_i++ ) { if( elements[elt_i] >= mesh->elementDomainCount ) { continue; } if( pointInElement( context, newPoint, elements[elt_i] ) ) { break; } } /* Did we find the element? */ if( elt_i < nElements ) { /* If so, call a function to locate the tetrahedra and interpolate. */ interpolateNode( context, newNode_i, elements[elt_i] ); } else { /* If not, then the new node finds itself outside the old mesh. In this scenario, we cannot interpolate the nodal values with any accuracy (without knowing more about the physical problem). So, we will leave the node with its old values and mark this node as not being interpolated so the user may deal with it. */ /* Stash the node index. */ IndexSet_Add( extNodes, newNode_i ); /* Copy across the old value. Note that this should be done using some other provided copy method. */ memcpy( (unsigned char*)meshExt->newNodes + newNode_i * mesh->nodeExtensionMgr->finalSize, (unsigned char*)mesh->node + newNode_i * mesh->nodeExtensionMgr->finalSize, mesh->nodeExtensionMgr->finalSize ); /* assert(0); */ } /* Free element array. */ FreeArray( elements ); } /* Dump the external nodes and delete the set. */ IndexSet_GetMembers( extNodes, &meshExt->nExternalNodes, &meshExt->externalNodes ); Stg_Class_Delete( extNodes ); }
/* Populate field variables by SPR */ void _SnacRemesher_RecoverNode( void* _context, unsigned node_lI ) { Snac_Context* context = (Snac_Context*)_context; Mesh* mesh = context->mesh; MeshLayout* layout = (MeshLayout*)mesh->layout; HexaMD* decomp = (HexaMD*)layout->decomp; NodeLayout* nLayout = layout->nodeLayout; Snac_Node* node = Snac_Node_At( context, node_lI ); Coord* coord = Snac_NodeCoord_P( context, node_lI ); Index nodeElementCount = context->mesh->nodeElementCountTbl[node_lI]; Index nodeElement_I; Element_DomainIndex* elements; gsl_matrix* matA; gsl_vector* vecaStrain[6]; gsl_vector* vecaStress[6]; gsl_vector* vecaMaterial_I; gsl_vector* vecaDensity; gsl_vector* vecbStrain[6]; gsl_vector* vecbStress[6]; gsl_vector* vecbMaterial_I; gsl_vector* vecbDensity; Index i,j; IJK ijk; Node_GlobalIndex node_gI = _MeshDecomp_Node_LocalToGlobal1D( decomp, node_lI ); Node_GlobalIndex gNodeI = decomp->nodeGlobal3DCounts[0]; Node_GlobalIndex gNodeJ = decomp->nodeGlobal3DCounts[1]; Node_GlobalIndex gNodeK = decomp->nodeGlobal3DCounts[2]; Node_GlobalIndex intNode_gI; Node_DomainIndex intNode_lI; unsigned int isBoundaryNode=0, patchCenterNum=1, patchCenterI, patchCenterList[2]; RegularMeshUtils_Node_1DTo3D( decomp, node_gI, &ijk[0], &ijk[1], &ijk[2] ); /* If boundary node, find a (topologically?) nearest interior node. Loosely following Khoei and Gharehbaghi, 2007, The superconvergent patch recovery techinique and data transfer operators in 3D plasticity problems, Finite Elements in Analysis and Design 43 (2007) 630-- 648. */ if( (gNodeI>2) && (ijk[0]==0) ) { ijk[0] += 1; isBoundaryNode = 1; } if( (gNodeI>2) && (ijk[0]==decomp->nodeGlobal3DCounts[0]-1) ) { ijk[0] -= 1; isBoundaryNode = 1; } if( (gNodeJ>2) && (ijk[1]==0) ) { ijk[1] += 1; isBoundaryNode = 1; } if( (gNodeJ>2) && (ijk[1]==decomp->nodeGlobal3DCounts[1]-1) ) { ijk[1] -= 1; isBoundaryNode = 1; } if( (gNodeK>2) && (ijk[2]==0) ) { ijk[2] += 1; isBoundaryNode = 1; } if( (gNodeK>2) && (ijk[2]==decomp->nodeGlobal3DCounts[2]-1) ) { ijk[2] -= 1; isBoundaryNode = 1; } /* node_lI itself always becomes a patch center, and if the current node is a boundary node, find an interior node and add it to the patch center list. */ patchCenterList[0] = node_lI; if( isBoundaryNode ) { patchCenterNum=2; intNode_gI = ijk[0]+gNodeI*ijk[1]+gNodeI*gNodeJ*ijk[2]; patchCenterList[1] = Mesh_NodeMapGlobalToLocal( mesh, intNode_gI ); } /* initialize gsl vectors and matrix. */ matA = gsl_matrix_alloc(4,4); gsl_matrix_set_zero( matA ); vecaMaterial_I = gsl_vector_alloc(4); gsl_vector_set_zero( vecaMaterial_I ); vecbMaterial_I = gsl_vector_alloc(4); gsl_vector_set_zero( vecbMaterial_I ); vecaDensity = gsl_vector_alloc(4); gsl_vector_set_zero( vecaDensity ); vecbDensity = gsl_vector_alloc(4); gsl_vector_set_zero( vecbDensity ); for(i=0;i<6;i++) { vecaStrain[i] = gsl_vector_alloc(4); gsl_vector_set_zero( vecaStrain[i] ); vecaStress[i] = gsl_vector_alloc(4); gsl_vector_set_zero( vecaStress[i] ); vecbStrain[i] = gsl_vector_alloc(4); gsl_vector_set_zero( vecbStrain[i] ); vecbStress[i] = gsl_vector_alloc(4); gsl_vector_set_zero( vecbStress[i] ); } /* For each patch center */ for( patchCenterI=0; patchCenterI < patchCenterNum; patchCenterI++ ) { /* For each incident element, find inicident tets. */ for( nodeElement_I = 0; nodeElement_I < nodeElementCount; nodeElement_I++ ) { Element_DomainIndex element_dI = context->mesh->nodeElementTbl[patchCenterList[patchCenterI]][nodeElement_I]; if( element_dI < mesh->elementDomainCount ) { Index elementTetra_I; Snac_Element* element = Snac_Element_At( context, element_dI ); /* Extract the element's node indices. Note that there should always be eight of these. */ { Element_GlobalIndex element_gI; elements = Memory_Alloc_Array( Node_DomainIndex, nodeElementCount, "SnacRemesher" ); element_gI = Mesh_ElementMapDomainToGlobal( mesh, element_dI ); nLayout->buildElementNodes( nLayout, element_gI, elements ); } /* Convert global node indices to domain. */ { unsigned eltNode_i; for( eltNode_i = 0; eltNode_i < nodeElementCount; eltNode_i++ ) { elements[eltNode_i] = Mesh_NodeMapGlobalToDomain( mesh, elements[eltNode_i] ); } } /* For each incident tetrahedron in the incident element, add up contributions to P, A, and b as in Zienkiewicz and Zhu (1992), p. 1336 */ for( elementTetra_I = 0; elementTetra_I < Node_Element_Tetrahedra_Count;elementTetra_I++ ) { Tetrahedra_Index tetra_I = NodeToTetra[nodeElement_I][elementTetra_I]; Coord tCrds[4]; double positionP[4] = {1.0,0.0,0.0,0.0}; Index ii,jj; /* Extract the tetrahedron's coordinates. */ Vector_Set( tCrds[0], mesh->nodeCoord[elements[TetraToNode[tetra_I][0]]] ); Vector_Set( tCrds[1], mesh->nodeCoord[elements[TetraToNode[tetra_I][1]]] ); Vector_Set( tCrds[2], mesh->nodeCoord[elements[TetraToNode[tetra_I][2]]] ); Vector_Set( tCrds[3], mesh->nodeCoord[elements[TetraToNode[tetra_I][3]]] ); for(ii=1;ii<4;ii++) for(jj=0;jj<4;jj++) positionP[ii] += (0.25f * tCrds[jj][ii-1]); for(ii=0;ii<4;ii++) { double tmp; tmp = gsl_vector_get(vecbStrain[0],ii) + positionP[ii]*element->tetra[tetra_I].strain[0][0]; gsl_vector_set(vecbStrain[0],ii,tmp); tmp = gsl_vector_get(vecbStrain[1],ii) + positionP[ii]*element->tetra[tetra_I].strain[1][1]; gsl_vector_set(vecbStrain[1],ii,tmp); tmp = gsl_vector_get(vecbStrain[2],ii) + positionP[ii]*element->tetra[tetra_I].strain[2][2]; gsl_vector_set(vecbStrain[2],ii,tmp); tmp = gsl_vector_get(vecbStrain[3],ii) + positionP[ii]*element->tetra[tetra_I].strain[0][1]; gsl_vector_set(vecbStrain[3],ii,tmp); tmp = gsl_vector_get(vecbStrain[4],ii) + positionP[ii]*element->tetra[tetra_I].strain[0][2]; gsl_vector_set(vecbStrain[4],ii,tmp); tmp = gsl_vector_get(vecbStrain[5],ii) + positionP[ii]*element->tetra[tetra_I].strain[1][2]; gsl_vector_set(vecbStrain[5],ii,tmp); tmp = gsl_vector_get(vecbStress[0],ii) + positionP[ii]*element->tetra[tetra_I].stress[0][0]; gsl_vector_set(vecbStress[0],ii,tmp); tmp = gsl_vector_get(vecbStress[1],ii) + positionP[ii]*element->tetra[tetra_I].stress[1][1]; gsl_vector_set(vecbStress[1],ii,tmp); tmp = gsl_vector_get(vecbStress[2],ii) + positionP[ii]*element->tetra[tetra_I].stress[2][2]; gsl_vector_set(vecbStress[2],ii,tmp); tmp = gsl_vector_get(vecbStress[3],ii) + positionP[ii]*element->tetra[tetra_I].stress[0][1]; gsl_vector_set(vecbStress[3],ii,tmp); tmp = gsl_vector_get(vecbStress[4],ii) + positionP[ii]*element->tetra[tetra_I].stress[0][2]; gsl_vector_set(vecbStress[4],ii,tmp); tmp = gsl_vector_get(vecbStress[5],ii) + positionP[ii]*element->tetra[tetra_I].stress[1][2]; gsl_vector_set(vecbStress[5],ii,tmp); /* tmp = gsl_vector_get(vecbMaterial_I,ii) + positionP[ii]*((double)(element->tetra[tetra_I].material_I)+0.5); */ tmp = gsl_vector_get(vecbMaterial_I,ii) + positionP[ii]*pow(10.0,(double)(element->tetra[tetra_I].material_I)); gsl_vector_set(vecbMaterial_I,ii,tmp); tmp = gsl_vector_get(vecbDensity,ii) + positionP[ii]*element->tetra[tetra_I].density; gsl_vector_set(vecbDensity,ii,tmp); for(jj=0;jj<4;jj++) { tmp = gsl_matrix_get(matA,ii,jj) + positionP[ii]*positionP[jj]; gsl_matrix_set(matA,ii,jj,tmp); } } /* end of verteces of a tet. */ } /* end of incident tets. */ } /* if within my domain */ } /* end of incident elements. */ } /* end of patchCenterI */ /* compute parameter vectors. */ { int s; gsl_permutation * p = gsl_permutation_alloc (4); gsl_linalg_LU_decomp (matA, p, &s); for(i=0;i<6;i++) { gsl_linalg_LU_solve (matA, p, vecbStrain[i], vecaStrain[i]); gsl_linalg_LU_solve (matA, p, vecbStress[i], vecaStress[i]); } gsl_linalg_LU_solve (matA, p, vecbMaterial_I, vecaMaterial_I); gsl_linalg_LU_solve (matA, p, vecbDensity, vecaDensity); /* printf ("x = \n"); */ /* gsl_vector_fprintf (stdout, x, "%g"); */ gsl_permutation_free (p); } /* zero the arrays to store recovered field. */ /* probably not necessary. */ /* for(i=0;i<6;i++) { */ /* node->strainSPR[i] = 0.0f; */ /* node->stressSPR[i] = 0.0f; */ /* } */ /* Recover using the parameter vectors. */ for(j=0;j<6;j++) { node->strainSPR[j] = gsl_vector_get(vecaStrain[j],0); node->stressSPR[j] = gsl_vector_get(vecaStress[j],0); for(i=0;i<3;i++) { node->strainSPR[j] += gsl_vector_get(vecaStrain[j],i+1)*(*coord)[i]; node->stressSPR[j] += gsl_vector_get(vecaStress[j],i+1)*(*coord)[i]; } } node->material_ISPR = gsl_vector_get(vecaMaterial_I,0); for(i=0;i<3;i++) node->material_ISPR += gsl_vector_get(vecaMaterial_I,i+1)*(*coord)[i]; node->densitySPR = gsl_vector_get(vecaDensity,0); for(i=0;i<3;i++) node->densitySPR += gsl_vector_get(vecaDensity,i+1)*(*coord)[i]; /* free gsl vectors and matrix. */ gsl_matrix_free( matA ); gsl_vector_free( vecaMaterial_I ); gsl_vector_free( vecbMaterial_I ); gsl_vector_free( vecaDensity ); gsl_vector_free( vecbDensity ); for(i=0;i<6;i++) { gsl_vector_free( vecaStrain[i] ); gsl_vector_free( vecaStress[i] ); gsl_vector_free( vecbStrain[i] ); gsl_vector_free( vecbStress[i] ); } /* Free the element node array. */ FreeArray( elements ); /* end of recovery. */ }
void _SnacRemesher_InterpolateNode( void* _context, unsigned nodeInd, unsigned elementInd, unsigned tetInd, unsigned* tetNodeInds, double* weights, Snac_Node* dstNodes ) { Snac_Context* context = (Snac_Context*)_context; Mesh* mesh = context->mesh; NodeLayout* nLayout = mesh->layout->nodeLayout; Snac_Node* dstNode = (Snac_Node*)ExtensionManager_At( context->mesh->nodeExtensionMgr, dstNodes, nodeInd ); unsigned tetNode_i; /* Extract the element's node indices. Note that there should always be eight of these. */ Node_DomainIndex* eltNodes; unsigned int nEltNodes = 8; { Element_GlobalIndex gEltInd; eltNodes = Memory_Alloc_Array( Node_DomainIndex, nEltNodes, "SnacRemesher" ); gEltInd = Mesh_ElementMapDomainToGlobal( mesh, elementInd ); nLayout->buildElementNodes( nLayout, gEltInd, eltNodes ); } /* Convert global node indices to local. */ { unsigned eltNode_i; for( eltNode_i = 0; eltNode_i < nEltNodes; eltNode_i++ ) { eltNodes[eltNode_i] = Mesh_NodeMapGlobalToDomain( mesh, eltNodes[eltNode_i] ); } } /* Clear the velocity. */ dstNode->velocity[0] = 0.0; dstNode->velocity[1] = 0.0; dstNode->velocity[2] = 0.0; dstNode->strainSPR[0] = 0.0; dstNode->strainSPR[1] = 0.0; dstNode->strainSPR[2] = 0.0; dstNode->strainSPR[3] = 0.0; dstNode->strainSPR[4] = 0.0; dstNode->strainSPR[5] = 0.0; dstNode->stressSPR[0] = 0.0; dstNode->stressSPR[1] = 0.0; dstNode->stressSPR[2] = 0.0; dstNode->stressSPR[3] = 0.0; dstNode->stressSPR[4] = 0.0; dstNode->stressSPR[5] = 0.0; dstNode->material_ISPR = 0.0; dstNode->densitySPR = 0.0; /* Loop over each contributing node. */ for( tetNode_i = 0; tetNode_i < 4; tetNode_i++ ) { Snac_Node* srcNode; /* Where is this contibution coming from? */ srcNode = Snac_Node_At( context, eltNodes[tetNodeInds[tetNode_i]] ); /* Add the contribution. */ // TODO: Do spherical part. dstNode->velocity[0] += srcNode->velocity[0] * weights[tetNode_i]; dstNode->velocity[1] += srcNode->velocity[1] * weights[tetNode_i]; dstNode->velocity[2] += srcNode->velocity[2] * weights[tetNode_i]; dstNode->strainSPR[0] += srcNode->strainSPR[0] * weights[tetNode_i]; dstNode->strainSPR[1] += srcNode->strainSPR[1] * weights[tetNode_i]; dstNode->strainSPR[2] += srcNode->strainSPR[2] * weights[tetNode_i]; dstNode->strainSPR[3] += srcNode->strainSPR[3] * weights[tetNode_i]; dstNode->strainSPR[4] += srcNode->strainSPR[4] * weights[tetNode_i]; dstNode->strainSPR[5] += srcNode->strainSPR[5] * weights[tetNode_i]; dstNode->stressSPR[0] += srcNode->stressSPR[0] * weights[tetNode_i]; dstNode->stressSPR[1] += srcNode->stressSPR[1] * weights[tetNode_i]; dstNode->stressSPR[2] += srcNode->stressSPR[2] * weights[tetNode_i]; dstNode->stressSPR[3] += srcNode->stressSPR[3] * weights[tetNode_i]; dstNode->stressSPR[4] += srcNode->stressSPR[4] * weights[tetNode_i]; dstNode->stressSPR[5] += srcNode->stressSPR[5] * weights[tetNode_i]; dstNode->material_ISPR += srcNode->material_ISPR * weights[tetNode_i]; dstNode->densitySPR += srcNode->densitySPR * weights[tetNode_i]; } }