void MultigridSolver_UpdateOps( MultigridSolver* self ) {
	MultigridSolver_Level*	level;
	//Matrix			**pOps, **rOps;
	Mat			*pOps, *rOps;
	unsigned		l_i;

	assert( self && Stg_CheckType( self, MultigridSolver ) );

	MGOpGenerator_Generate( self->opGen, &pOps, &rOps );
	for( l_i = 1; l_i < self->nLevels; l_i++ ) {
		level = self->levels + l_i;

		//if( !level->P ) {
		if( level->P == PETSC_NULL ) {
			level->P = pOps[l_i];
			//Stg_Class_AddRef( level->P );
		}
		else
			Stg_MatDestroy(&pOps[l_i] );
			//Stg_Class_RemoveRef( pOps[l_i] );


		//if( !level->R ) {
		if( level->R == PETSC_NULL ) {
			level->R = rOps[l_i];
			//Stg_Class_AddRef( level->R );
		}
		else
			Stg_MatDestroy(&rOps[l_i] );
			//Stg_Class_RemoveRef( rOps[l_i] );
	}

	FreeArray( pOps );
	FreeArray( rOps );
}
void PETScMGSolver_UpdateOps( PETScMGSolver* self ) {
	PC		pc;
	Mat		*pOps, *rOps;
	PetscErrorCode	ec;
	unsigned	l_i;

	assert( self && Stg_CheckType( self, PETScMGSolver ) );

	ec = KSPGetPC( self->mgData->ksp, &pc );
	CheckPETScError( ec );

	MGOpGenerator_Generate( self->opGen, (Mat**)&pOps, (Mat**)&rOps );

	for( l_i = 1; l_i < self->nLevels; l_i++ ) {
		//assert( Stg_CheckType( pOps[l_i], PETScMatrix ) );
		//assert( Stg_CheckType( rOps[l_i], PETScMatrix ) );

		PETScMGSolver_SetProlongation( self, l_i, pOps[l_i] );
#if( ((PETSC_VERSION_MAJOR==2) && (PETSC_VERSION_MINOR==3) && (PETSC_VERSION_SUBMINOR==3)) || (PETSC_VERSION_MAJOR==3) )
			ec = PCMGSetInterpolation( pc, l_i, pOps[l_i] );
#else
			ec = PCMGSetInterpolate( pc, l_i, pOps[l_i] );
#endif
		CheckPETScError( ec );

		PETScMGSolver_SetRestriction( self, l_i, rOps[l_i] );
		ec = PCMGSetRestriction( pc, l_i, rOps[l_i] );
		CheckPETScError( ec );
	}

	FreeArray( pOps );
	FreeArray( rOps );
}
Пример #3
0
void Function_Destroy(lua_State* L, Function* function, bool releaseRefs)
{

    if (releaseRefs)
    {
        Gc* gc = &L->gc;
        Gc_DecrementReference(L, gc, function->constants);
        if (function->parent != NULL)
        {
            Gc_DecrementReference(L, gc, function->parent);
        }
        for (int i = 0; i < function->numFunctions; ++i)
        {
            Gc_DecrementReference(L, gc, function->function[i]);
        }
        for (int i = 0; i < function->numUpValues; ++i)
        {
            Gc_DecrementReference(L, gc, function->upValue[i]);
        }
        for (int i = 0; i < function->numLocals; ++i)
        {
            Gc_DecrementReference(L, gc, function->local[i]);
        }
    }

    FreeArray(L, function->function, function->maxFunctions);
    FreeArray(L, function->code, function->maxCodeSize);
    FreeArray(L, function->sourceLine, function->maxSourceLines);
    Free(L, function, sizeof(Function));

}
Пример #4
0
void STreeNode_Destroy( STreeNode *self, STree *tree ) {
   if ( self->left )
      STreeNode_Destroy( self->left, tree );
   if ( self->right )
      STreeNode_Destroy( self->right, tree );
   tree->del( self->data );
   FreeArray( self->data );
   FreeArray( self );
}
Пример #5
0
void NRSOLUTION::InitPFlow()
{
	FreeArray(RightP); FreeArray(RightQ);

	MAXITER = 100; MAXPERR = MAXQERR = 0.005f;
	IsInit = pNet->m_ChangeCode;

	NRSBusTotal = pNet->iGetBusTotal();
	Volt = pNet->BusVolt; Sita = pNet->BusSita;
	MallocNew(RightP, real, NRSBusTotal);
	MallocNew(RightQ, real, NRSBusTotal);
	m_Solver->InitMatrix(pNet->m_Matrix);
}
Пример #6
0
Bool testIndices( unsigned rank, unsigned nProcs, unsigned watch ) {
    Bool		result = True;
    unsigned	nInds = 100;
    unsigned	inds[100];
    RangeSet*	set;
    unsigned	nDstInds;
    unsigned*	dstInds;
    unsigned	i;

    for( i = 0; i < nInds; i++ )
        inds[i] = i;

    set = RangeSet_New();

    RangeSet_SetIndices( set, nInds, inds );
    if( rank == watch ) {
        if( set->nInds != nInds ||
                set->nRanges != 1 )
        {
            result = False;
            goto done;
        }
    }

    RangeSet_GetIndices( set, &nDstInds, &dstInds );
    if( rank == watch ) {
        unsigned	ind_i;

        if( nDstInds != nInds ) {
            FreeArray( dstInds );
        }

        for( ind_i = 0; ind_i < nDstInds; ind_i++ ) {
            if( dstInds[ind_i] != inds[ind_i] )
                break;
        }
        if( ind_i < nDstInds ) {
            result = False;
            goto done;
        }
    }

done:
    FreeArray( dstInds );
    FreeObject(set );

    return result;
}
Пример #7
0
void IGraph_SetRemoteElements( void* _self, int dim, int nEls, const int* globals ) {
    IGraph* self = (IGraph*)_self;
    int nDoms;
    int d_i, e_i;

    assert( self );
    assert( dim < self->nTDims );
    assert( !nEls || globals );
    for( d_i = 0; d_i < self->nTDims; d_i++ ) {
        if( self->nIncEls[dim][d_i] ) {
            for( e_i = Decomp_GetNumLocals( self->locals[dim] ); e_i < Sync_GetNumDomains( self->remotes[dim] ); e_i++ ) {
                FreeArray( self->incEls[dim][d_i][e_i] );
            }
        }
    }

    Sync_SetRemotes( self->remotes[dim], nEls, globals );

    for( d_i = 0; d_i < self->nTDims; d_i++ ) {
        if( self->nIncEls[dim][d_i] ) {
            nDoms = Sync_GetNumDomains( self->remotes[dim] );
            self->nIncEls[dim][d_i] = ReallocArray( self->incEls[dim][d_i], int, nDoms );
            self->incEls[dim][d_i] = ReallocArray( self->incEls[dim][d_i], int*, nDoms );

            for( e_i = Decomp_GetNumLocals( self->locals[dim] ); e_i < nDoms; e_i++ ) {
                self->nIncEls[dim][d_i][e_i] = 0;
                self->incEls[dim][d_i][e_i] = NULL;
            }
        }
    }
Пример #8
0
void ISet_SetMaxSize( void* _self, int maxSize ) {
   ISet* self = (ISet*)_self;
   int nOldItms, *keys;
   ISetItem* itm;
   int i_i;

   pcu_assert( self );
   nOldItms = self->curSize;
   keys = AllocArray( int, self->curSize );
   ISet_GetArray( self, keys );

   ISet_Clear( self );
   self->maxSize = maxSize;
   self->curSize = 0;
   self->tblSize = (int)((double)maxSize * ISet_TableFactor);
   self->tblSize += (self->tblSize % 2) ? 0 : 1;
   self->tbl = (ISetItem*)ReallocArray( self->tbl, ISetItem, self->tblSize );
   for( i_i = 0; i_i < self->tblSize; i_i++ ) {
      itm = self->tbl + i_i;
      itm->key = 0;
      itm->next = NULL;
   }
   self->used = (Bool*)ReallocArray( self->used, Bool, self->tblSize );
   memset( self->used, 0, self->tblSize* sizeof(Bool) );

   for( i_i = 0; i_i < nOldItms; i_i++ )
      ISet_Insert( self, keys[i_i] );
   FreeArray( keys );
}
Пример #9
0
void _MeshGenerator_Delete( void* meshGenerator ) {
	MeshGenerator*	self = (MeshGenerator*)meshGenerator;

	FreeArray( self->meshes );

	/* Delete the parent. */
	_Stg_Component_Delete( self );
}
Пример #10
0
void DEC_FIXP_LDPC_BIN::Free()
{
    FreeMatrix(ptChkMess);  // extrinsic messages from check to variable nodes
    FreeMatrix(ptVarMess);  // extrinsic messages from variable to check nodes
    FreeArray(ptPostInfo);  // store the pseudo-posterior log-likelihood ratios (LLR)
    FreePointer(ptFixp);    // pointer to fixed-point arithmetic class

}   // end of 'Free' method
Пример #11
0
void IGraph_SetLocalElements( void* _self, int dim, int nEls, const int* globals ) {
    IGraph* self = (IGraph*)_self;
    int d_i, e_i;

    assert( self );
    assert( dim < self->nTDims );
    assert( !nEls || globals );
    for( d_i = 0; d_i < self->nTDims; d_i++ ) {
        for( e_i = 0; e_i < Sync_GetNumDomains( self->remotes[dim] ); d_i++ )
            FreeArray( self->incEls[dim][d_i][e_i] );
        FreeArray( self->incEls[dim][d_i] );
        FreeArray( self->nIncEls[dim][d_i] );
        self->incEls[dim][d_i] = NULL;
        self->nIncEls[dim][d_i] = NULL;
    }
    Decomp_SetLocals( self->locals[dim], nEls, globals );
    Sync_SetDecomp( self->remotes[dim], self->locals[dim] );
}
Пример #12
0
void BUSINFO::FreeSpace()
{
	int i;
	for (i = 0; i < _MaxBusNo; i++)
	{
		FreeArray(Bus[i]);
	}
	BusTotal = 0;
	m_BusHash.InitHashTable(_MaxBusNo);
}
Пример #13
0
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 _TrilinearElementType_Destroy( void* elementType, void *data ){
	TrilinearElementType* 	self = (TrilinearElementType*)elementType;

	Memory_Free( self->faceNodes );
	Memory_Free( self->evaluatedShapeFunc );
	Memory_Free( self->GNi );

	FreeArray( self->tetInds );

	_ElementType_Destroy( self, data );
}
Пример #15
0
HRESULT GLScript_Array::ScanArray (int type, BSTR pArrayConfig) {
	// make a temp copy of the array config string 
	wchar_t *pTempArrayConfig = (wchar_t *)::SysAllocString (pArrayConfig);
	if (pTempArrayConfig == NULL) {
		return E_OUTOFMEMORY;
	}

	// scan array config for elements
	wchar_t *ptr = pTempArrayConfig;
	int length = 0;
	while (*ptr != _T('\0')) {
		// if its , symbol terminate
		if (*ptr == _T(',')) {
			*ptr = _T('\0');
			++length;
		}
		++ptr; // next character
	}
	if (ptr > pTempArrayConfig)
		++length;

	// allocate new data array if required
	void *ptrData = NULL;

	if (length >= 0) {
		ptrData = AllocArray (type, length);
		if (!ptrData) {
			// free temp array config string
			::SysFreeString (pTempArrayConfig);
			return E_OUTOFMEMORY;
		}

		// convert array elements
		if (!ConvertArrayElements (type, pTempArrayConfig, length, ptrData)) {
			// do cleanup and return error
			::SysFreeString (pTempArrayConfig);
			delete [] pTempArrayConfig;
			return E_INVALIDARG;
		}
	}

	// release old array data
	FreeArray ();

	// set new array data
	m_data = ptrData;
	m_length = length;
	m_type = type;

	// free the temp copy of array config string
	::SysFreeString (pTempArrayConfig);
	return NOERROR;
}
Пример #16
0
STreeNode* STree_Rebalance( void* _self, STreeNode *root, int nNodes ) {
   //STree* self = (STree*)_self;
   STreeNode *pseudo, *tmp;

   pseudo = AllocArray( STreeNode, 1 );
   pseudo->left = NULL;
   pseudo->right = root;
   pseudo->data = NULL;
   STree_Flatten( pseudo );
   STree_Grow( pseudo, nNodes );
   tmp = pseudo->right;
   FreeArray( pseudo );

   return tmp;
}
int main()
{
	SetArraySize(2);
	assert( 2 == g_arraysize); // test-driven development (TDD)
	assert( 0 == p_arraydata[1]);

	SetValue( 0, 1.0);
	SetValue( 1, 2.0);
	assert( 2.0 == p_arraydata[1]);

	PrintArray();

	FreeArray();
	assert ( 0 == g_arraysize);
	assert ( 0 == p_arraydata);

    return 0;
}
Пример #18
0
void SROpGenerator_GenLevelMesh( SROpGenerator* self, unsigned level ) {
	Stream*			errorStream = Journal_Register( ErrorStream_Type, (Name)"SROpGenerator::GenLevelMesh"  );
	Mesh			*fMesh, *cMesh;
	CartesianGenerator	*fGen, *cGen;
	unsigned		nDims;
	unsigned*		cSize;
	double			crdMin[3], crdMax[3];
	unsigned		d_i;

	assert( self && Stg_CheckType( self, SROpGenerator ) );
	assert( self->meshes );
	assert( level < self->nLevels );

	fMesh = self->meshes[level + 1];
	nDims = Mesh_GetDimSize( fMesh );
	fGen = (CartesianGenerator*)fMesh->generator;
	Journal_Firewall( fGen && !strcmp( fGen->type, CartesianGenerator_Type ),
			  errorStream,
			  "\n" \
			  "****************************************************************\n" \
			  "* Error: Simple regular multigrid operator generation requires *\n" \
			  "*        a fine mesh that has been generated with a            *\n" \
			  "*        cartesian generator.                                  *\n" \
			  "****************************************************************\n" \
			  "\n" );

	cGen = CartesianGenerator_New( "", NULL );
	CartesianGenerator_SetDimSize( cGen, nDims );
	cSize = AllocArray( unsigned, nDims );
	for( d_i = 0; d_i < nDims; d_i++ )
		cSize[d_i] = fGen->elGrid->sizes[d_i] / 2;
	CartesianGenerator_SetTopologyParams( cGen, cSize, fGen->maxDecompDims, fGen->minDecomp, fGen->maxDecomp );
	Mesh_GetGlobalCoordRange( fMesh, crdMin, crdMax );
	CartesianGenerator_SetGeometryParams( cGen, crdMin, crdMax );
	CartesianGenerator_SetShadowDepth( cGen, 0 );
	FreeArray( cSize );

	cMesh = (Mesh*)FeMesh_New( "" );
	Mesh_SetGenerator( cMesh, cGen );
	FeMesh_SetElementFamily( cMesh, ((FeMesh*)fMesh)->feElFamily );
	Stg_Component_Build( cMesh, NULL, False );
	Stg_Component_Initialise( cMesh, NULL, False );
	self->meshes[level] = cMesh;
}
Пример #19
0
void ISet_Clear( void* _self ) {
   ISet* self = (ISet*)_self;
   ISetItem *itm, *cur, *nxt;
   int i_i;

   pcu_assert( self );
   for( i_i = 0; i_i < self->tblSize; i_i++ ) {
      self->used[i_i] = False;
      itm = self->tbl + i_i;
      cur = itm->next;
      while( cur ) {
	 nxt = cur->next;
	 FreeArray( cur );
	 cur = nxt;
      }
      itm->next = NULL;
   }
   self->curSize = 0;
}
Пример #20
0
Bool ISet_TryRemove( void* _self, int key ) {
   ISet* self = (ISet*)_self;
   ISetItem *itm, *prev, *toDel;
   int ind;

   pcu_assert( self );
   ind = ISet_Hash( self, key );
   pcu_assert( ind < self->tblSize );
   if( !self->used[ind] )
      return False;
   itm = self->tbl + ind;
   if( itm->key == key ) {
      toDel = itm->next;
      if( toDel ) {
	 itm->key = toDel->key;
	 itm->next = toDel->next;
      }
      else
	 self->used[ind] = False;
   }
   else {
      prev = itm;
      toDel = itm->next;
      while( toDel ) {
	 if( toDel->key == key ) {
	    prev->next = toDel->next;
	    break;
	 }
	 prev = toDel;
	 toDel = toDel->next;
      }
      if( !toDel )
	 return False;
   }
   if( toDel )
      FreeArray( toDel );
   self->curSize--;
   return True;
}
Пример #21
0
int main (void)
{
    unsigned long T;

    /* Show info at start */
    ShowInfo ();

    /* Remember the time */
    T = clock ();

    /* Do the tests */
    FillArray ();
    ShowInfo ();
    FreeArray ();
    ShowInfo ();

    /* Calculate the time and print it */
    T = clock () - T;
    printf ("Time needed: %lu ticks\n", T);

    /* Done */
    return EXIT_SUCCESS;
}
Пример #22
0
HRESULT GLScript_Array::CreateWithTypeAndLength (int type, int length) {
	if (!CheckArrayType(type)) {
		return E_INVALIDARG;;
	}
	if (length < 0) {
		return E_INVALIDARG;
	}

	// release old array data
	FreeArray ();

	// set new array data
	m_data = AllocArray (type, length);

	if (m_data == NULL) {
		return E_OUTOFMEMORY;
	}

	m_length = length;
	m_type = type;

	return NOERROR;
}
Пример #23
0
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 );
}
Пример #24
0
int BPA_DYNAMICMODELINFO::Net_ReadBPALine(char*tFileName)
{
	char Line[_MaxBPALineLen_];
	char(*LineST)[_MaxBPALineLen_]; int *IsRead = NULL; int *IsChange = NULL;
	int i, j, flag, LineTotal = 0;//增加该功能,支持一行读到尾,并舍弃

	//第一步,将文件读入到LineST数组中
	FILE*	fpPFfile;
	fpPFfile = fopen(tFileName, "rb");
	if (fpPFfile == NULL)
		return 0;
	while (fgets(Line, _MaxBPALineLen_, fpPFfile))
		LineTotal++;
	rewind(fpPFfile);
	MallocCharArray(LineST, (LineTotal + 4), _MaxBPALineLen_);
	i = 0;
	int flagAddLine = 0;
	while (fgets(Line, _MaxBPALineLen_, fpPFfile))
	{
		if (flagAddLine == 1)
		{
			if (strlen(Line) < _MaxBPALineLen_ - 1)
				flagAddLine = 0;
			continue;
		}
		if (strlen(Line) >= _MaxBPALineLen_ - 1)
		{
			if (Line[_MaxBPALineLen_ - 2] != 10 && Line[_MaxBPALineLen_ - 2] != 13)
			{//这里考虑到有些刚好_MaxBPALineLen_-2个字符的行
				flagAddLine = 1;//表示该行还未读完
			}
		}
		if (strlen(Line) > 3 && Line[0] == '(' && Line[1] == 'E' && Line[2] == 'N' && Line[3] == 'D')
			break;//终止符(END)
		if (strlen(Line) > 3 && Line[0] == '/' && (Line[1] == 'M' && Line[2] == 'V' && Line[3] == 'A'
			|| Line[1] == ' ' && Line[2] == 'M' && Line[3] == 'V' && Line[4] == 'A'))
		{//读入"/MVA_BASE = 1000\"卡//problem此处还存在问题
			char *ex;
			if ((ex = strrchr(Line, '=')) != NULL)
			{
				SetBMVA((float)atof(++ex));
			}
		}
		if (strlen(Line) == 0
			|| Line[0] == '-'
			|| Line[0] == 'C' || Line[0] == 'H' || Line[0] == '.' || Line[0] == ' '//注释 空行
			|| Line[0] == '(' || Line[0] == '[' || Line[0] == '/' || Line[0] == '\\' || Line[0] == '>'//控制命令
			|| Line[0] == 10 || Line[0] == 13)//换行符 回车符
			continue;
		strncpy(LineST[i], Line, _MaxBPALineLen_);
		i++;
	}
	fclose(fpPFfile);
	LineTotal = i;
	MallocNew(IsRead, int, LineTotal); memset(IsRead, 0, LineTotal*sizeof(int));
	MallocNew(IsChange, int, LineTotal); memset(IsChange, 0, LineTotal*sizeof(int));
	for (i = 0; i < LineTotal; i++)
	{
		if (LineST[i][2] == 'D' || LineST[i][2] == 'A' || LineST[i][2] == 'R')
		{
			IsChange[i] = 1;
		}
		if (LineST[i][0] == 'P' || LineST[i][0] == 'Z' || LineST[i][0] == 'D')
		{
			IsChange[i] = 1;
		}
	}
	//读入数据
	BPABUS *tempBus;
	BPABRANCH *tempBranchBase;
	for (i = 0; i < LineTotal; i++)
		//for (i = LineTotal-1; i >=0; i--)
	{
		if (IsRead[i] != 0)continue;
		if (IsChange[i] != 0)continue;//这里输入的是常规数据,不包含修改卡
		flag = 0;
		switch (LineST[i][0])
		{
		case 'A':
			flag = Area_ReadBPALine(LineST[i]);
			break;
		case 'B':
			tempBus = new BPABUS();
			flag = tempBus->ReadLine(LineST[i]);
			if (flag != 1)
			{
				delete tempBus;
				flag = 0;
			}
			else{
				flag = cpGetBusInfo()->AddNewBus(tempBus);
				if (flag < 0)
				{
					delete tempBus;
					flag = 0;
				}
				else{
					BPABus[flag] = tempBus;
					flag = 1;
				}
			}
			break;
		case 'L':
			if (LineST[i][1] == '+')
				break;//跳过L+卡
			if (LineST[i][1] == ' ')
			{
				tempBranchBase = new LBRANCH();
				flag = tempBranchBase->ReadLine(LineST[i]);
				if (flag != 1)
				{
					delete tempBranchBase;
					flag = 0;
				}
				else{
					flag = cpGetBranchInfo()->AddNewBranch(tempBranchBase);
					if (flag < 0)
					{
						delete tempBranchBase;
						flag = 0;
					}
					else{
						BPABranch[flag] = tempBranchBase;
						flag = 1;
					}
				}
			}
			break;
		case 'E':
			tempBranchBase = new EBRANCH();
			flag = tempBranchBase->ReadLine(LineST[i]);
			if (flag != 1)
			{
				delete tempBranchBase;
				flag = 0;
			}
			else{
				flag = cpGetBranchInfo()->AddNewBranch(tempBranchBase);
				if (flag < 0)
				{
					delete tempBranchBase;
					flag = 0;
				}
				else
					flag = 1;
			}
			break;
		case 'T':
			if (LineST[i][1] == 'P')
				tempBranchBase = new TPBRANCH();
			else
				tempBranchBase = new TBRANCH();
			flag = tempBranchBase->ReadLine(LineST[i]);
			if (flag != 1)
			{
				delete tempBranchBase;
				flag = 0;
			}
			else{
				flag = cpGetBranchInfo()->AddNewBranch(tempBranchBase);
				if (flag < 0)
				{
					delete tempBranchBase;
					flag = 0;
				}
				else
					flag = 1;
			}
			break;
		}
		if (flag == 1)IsRead[i] = 1;
	}

	SortBusByName tSort(this);
	tSort.QikSort(iGetBusTotal());
	cpGetBusInfo()->ResetHashTable();

	NetLink();

	char Name1[_MaxNameLen], Name2[_MaxNameLen], BranchName[_MaxNameLen], ID;
	float BaseKv1, BaseKv2;
	char CID[2];
	int BusIndex, BranchIndex;
	char Zone[_MaxNameLen]; int tZoneNo; float LoadPper, LoadQper, GenPper, GenQper;
	for (i = 0; i < LineTotal; i++)
	{
		if (IsRead[i] != 0)continue;
		//if(IsChange[i]!=1)continue;
		flag = 0;
		switch (LineST[i][0])
		{
		case '+':
			GetItemFromLine(LineST[i], Name1, PLUS_Para[1], PLUS_Loca[1]); ReplaceName(Name1, _MaxNameLen);
			GetItemFromLine(LineST[i], (void*)(&BaseKv1), PLUS_Para[2], PLUS_Loca[2]);
			BusIndex = BPABusSearch(Name1, BaseKv1);
			if (BusIndex < 0)
			{
				sprintf(ErrorMessage[0], "找不到母线:%s", LineST[i]);
				cpGetErrorInfo()->PrintWarning(1, 1);
				break;
			}
			flag = cpGetBus(BusIndex)->ReadLine(LineST[i]);
			break;
		case 'L':
			if (LineST[i][1] == '+')
			{
				GetItemFromLine(LineST[i], (void*)(Name1), LPLUS_Para[1], LPLUS_Loca[1]);
				GetItemFromLine(LineST[i], (void*)(&BaseKv1), LPLUS_Para[2], LPLUS_Loca[2]);
				GetItemFromLine(LineST[i], (void*)(Name2), LPLUS_Para[4], LPLUS_Loca[4]);
				GetItemFromLine(LineST[i], (void*)(&BaseKv2), LPLUS_Para[5], LPLUS_Loca[5]);
				GetItemFromLine(LineST[i], (void*)(&CID), LPLUS_Para[6], LPLUS_Loca[6]);
				ID = CID[0];
				GenerateBPABranchName(BranchName, Name1, BaseKv1, Name2, BaseKv2, ID);
				BranchIndex = BranchSearch(BranchName);
				if (BranchIndex < 0)
				{
					sprintf(ErrorMessage[0], "找不到线路:%s", LineST[i]);
					cpGetErrorInfo()->PrintWarning(1, 1);
					break;
				}
				flag = cpGetBranch(BranchIndex)->ReadLine(LineST[i]);
			}
			break;
		case 'P':
			if (LineST[i][1] == 'Z')
			{
				GetItemFromLine(LineST[i], Zone, PZ_Para[0], PZ_Loca[0]); ReplaceName(Zone, _MaxNameLen);
				GetItemFromLine(LineST[i], &LoadPper, PZ_Para[1], PZ_Loca[1]);
				GetItemFromLine(LineST[i], &LoadQper, PZ_Para[2], PZ_Loca[2]);
				GetItemFromLine(LineST[i], &GenPper, PZ_Para[3], PZ_Loca[3]);
				GetItemFromLine(LineST[i], &GenQper, PZ_Para[4], PZ_Loca[4]);
				if (fabs(GenPper - 1.0) > 0.0001 || fabs(GenQper - 1.0) > 0.0001
					|| LoadPper<-0.0001 || LoadPper>1.0001
					|| LoadQper<-0.0001 || LoadQper>1.0001)
				{
					flag = 0;
					break;
				}
				if (fabs(GenPper) < 0.0001)GenPper = 1.f;
				if (fabs(GenQper) < 0.0001)GenQper = 1.f;
				if (fabs(GenPper - 1.0) > 0.0001 || fabs(GenQper - 1.0) > 0.0001
					|| LoadPper < -0.0001 || LoadQper < -0.0001)
				{
					sprintf(ErrorMessage[0], "PZ卡目前无法处理发电机的修改,忽略卡片:%s", LineST[i]);
					cpGetErrorInfo()->PrintWarning(1, 1);
					flag = 0;
					break;
				}
				tZoneNo = cpGetAreaInfo()->iGetZoneNo(Zone);
				if (tZoneNo < 0)
				{
					sprintf(ErrorMessage[0], "找不到区域名%s, 忽略卡片: %s", Zone, LineST[i]);
					cpGetErrorInfo()->PrintWarning(-1, 1);
					flag = 1;
					break;
				}
				for (j = 0; j < iGetBusTotal(); j++)
				{
					if (cpGetBus(j)->ZoneNo == tZoneNo)
					{
						if (cpGetBus(j)->cBusType == 'B')
						{
							((BPABUS*)cpGetBus(j))->m_fBusPLoadPer = LoadPper;
							((BPABUS*)cpGetBus(j))->m_fBusQLoadPer = LoadQper;
						}
					}
				}
				flag = 1;
			}
			break;
		}
		if (flag == 1)IsRead[i] = 1;
	}
#ifdef _DEBUG
	for (i = 0; i < LineTotal; i++)
	{
		if (IsRead[i]>0)continue;
		sprintf(ErrorMessage[0], "  不能识别的数据卡:%s", LineST[i]);
		cpGetErrorInfo()->PrintWarning(8, 1);
	}
#endif
	free(LineST); FreeArray(IsRead); FreeArray(IsChange);
	//cpGetErrorInfo()->CheckMessageType(8);//查看未识别卡片数
	cpGetErrorInfo()->CheckMessageType(1);//查看错误数据数
	cpGetErrorInfo()->CheckMessageType(6);//检查越限错误

	m_ChangeCode++;

	NetLink();
	return 1;
}
Пример #25
0
void STree_Remove( void* _self, const void* itm ) {
   STree* self = (STree*)_self;
   STreeNode *cur = self->root, **pre = &self->root;
   int res;

   assert( itm );
   assert( self->cmp );
   while( (res = self->cmp( itm, cur->data )) ) {
      if ( res < 0 ) {
	 pre = &cur->left;
	 cur = cur->left;
      }
      else {
	 pre = &cur->right;
	 cur = cur->right;
      }
   }
   assert( cur );
   if ( !cur->left )
      *pre = cur->right;
   else if ( !cur->right )
      *pre = cur->left;
   else if ( !cur->left->right ) {
      *pre = cur->left;
      cur->left->right = cur->right;
   }
   else if ( !cur->right->left ) {
      *pre = cur->right;
      cur->right->left = cur->left;
   }
   else if ( self->flip ) {
      STreeNode *last = cur->left, *preLast;
      while ( last->right ) {
	 preLast = last;
	 last = last->right;
      }
      preLast->right = last->left;
      last->left = cur->left;
      last->right = cur->right;
      *pre = last;
      self->flip = 0;
   }
   else {
      STreeNode *last = cur->right, *preLast;
      while ( last->left ) {
	 preLast = last;
	 last = last->left;
      }
      preLast->left = last->right;
      last->right = cur->right;
      last->left = cur->left;
      *pre = last;
      self->flip = 1;
   }
   self->del( cur->data );
   FreeArray( cur->data );
   FreeArray( cur );
   if ( --self->nNodes <= self->maxNodes / 2 ) {
      self->root = STree_Rebalance( self, self->root, self->nNodes );
      self->maxNodes = self->nNodes;
   }
}
Пример #26
0
GLScript_Array::~GLScript_Array () {
	FreeArray ();
}
Пример #27
0
int BPA_DYNAMICMODELINFO::ReadBPAFile(char*datfile, char*swifile)
{
	int flag;
	flag = Net_ReadBPALine(datfile);
	if (flag != 1)
		return flag;

	char Line[_MaxBPALineLen_];
	char(*LineST)[_MaxBPALineLen_]; int *IsRead = NULL;
	int i, LineTotal = 0, Line90No = -1;//增加该功能,支持一行读到尾,并舍弃

	//第一步,将文件读入到LineST数组中
	FILE*	fpPFfile;
	fpPFfile = fopen(swifile, "rb");
	if (fpPFfile == NULL)
		return 0;
	while (fgets(Line, _MaxBPALineLen_, fpPFfile))
		LineTotal++;
	rewind(fpPFfile);
	MallocCharArray(LineST, (LineTotal + 4), _MaxBPALineLen_);
	i = 0;
	while (fgets(Line, _MaxBPALineLen_, fpPFfile))
	{
		if (strlen(Line) > 1 && Line[0] == '9' && Line[1] == '9')
			break;//终止符99
		if (strlen(Line) > 1 && Line[0] == '9' && Line[1] == '0')
		{
			if (Line90No >= 0)
			{
				sprintf(ErrorMessage[0], "有多张90卡,数据出错");
				cpGetErrorInfo()->PrintError(1);
				return 0;
			}
			Line90No = i;
			continue;
		}
		if (strlen(Line) == 0
			|| Line[0] == '.' || Line[0] == ' '//注释 空行
			|| Line[0] == 10 || Line[0] == 13)//换行符 回车符
			continue;
		strncpy(LineST[i], Line, _MaxBPALineLen_);
		i++;
	}
	fclose(fpPFfile);
	LineTotal = i;
	if (Line90No < 0)Line90No = LineTotal;
	MallocNew(IsRead, int, LineTotal); memset(IsRead, 0, LineTotal*sizeof(int));

	//读入模型数据
	for (i = 0; i < Line90No; i++)
	{
		if (IsRead[i] != 0)continue;
		flag = 0;
		switch (LineST[i][0])
		{
		case 'C'://注释卡
			flag = 1;
			break;
		case 'L':
			if (LineST[i][1] == 'S')
			{//LS卡
				flag = 1;
			}
			else if (LineST[i][1] == 'N')
			{//LN卡
				flag = LN_ReadBPALine(LineST[i]);
			}
			break;
		case 'M':
			if (LineST[i][1] == 'C')
			{
				flag = MC_ReadBPALine(LineST[i]);
			}
			break;
		case 'F':
			if (LineST[i][1] == 'F')
			{
				flag = FF_ReadBPALine(LineST[i]);
			}
			break;
		}
		if (flag == 1)IsRead[i] = 1;
	}
	cpGetErrorInfo()->CheckMessageType(15);
	//索引连接
	int equipno;
	EQUIPMENT_DYN_MODEL*tEqipModel;
	for (i = 0; i < DynamicModelTotal; i++)
	{
		equipno = EquipSearch(DynamicModel[i]->EquipmentName);
		if (equipno < 0)
		{
			sprintf(ErrorMessage[0], "ERROR: 没有找到模型对应的设备");
			DynamicModel[i]->PrintInfo(ErrorMessage[1]);
			cpGetErrorInfo()->PrintWarning(13, 2);
			continue;
		}
		DynamicModel[i]->EquipIndex = equipno;
		DynamicModel[i]->pEquip = cpGetEquip(equipno);
		tEqipModel = DynamicModel[i]->IsEquipModel();
		if (tEqipModel != NULL)
		{
			cpGetEquip(equipno)->SetEquipModel(tEqipModel);
		}
	}
	cpGetErrorInfo()->CheckMessageType(13);
	//读入输出卡
	char tBusName[_MaxNameLen], tID;
	float tBaseKV;
	for (i = Line90No; i < LineTotal; i++)
	{
		if (IsRead[i] != 0)continue;
		flag = 0;
		switch (LineST[i][0])
		{
		case 'M'://输出设置卡
			if (LineST[i][1] == 'H')
				flag = 1;
			break;
		case 'G':
			if (LineST[i][1] == 'H')
			{//GH卡
				flag = GH_ReadBPALine(LineST[i]);
			}
			else
			{//发电机输出卡
				GetItemFromLine(LineST[i], tBusName, OUT_GEN_Para[0], OUT_GEN_Loca[0]);
				GetItemFromLine(LineST[i], &tBaseKV, OUT_GEN_Para[1], OUT_GEN_Loca[1]);
				GetItemFromLine(LineST[i], &tID, OUT_GEN_Para[2], OUT_GEN_Loca[2]);
				equipno = BPAGenSearch(tBusName, tBaseKV, tID);
				tEqipModel = cpGetEquip(equipno)->GetEquipModel();
				if (tEqipModel == NULL)
				{
					sprintf(ErrorMessage[0], "输出数据没有对应的模型:%s", Line);
					cpGetErrorInfo()->PrintWarning(-1, 1);
					continue;
				}
				flag = tEqipModel->ReadOutLine(LineST[i]);
				if (flag != 1)
				{
					sprintf(ErrorMessage[0], "输出数据读取失败:%s", Line);
					cpGetErrorInfo()->PrintWarning(11, 1);
				}
			}
			break;
		case 'B':
			if (LineST[i][1] == 'H')
			{
			}
			else{
				GetItemFromLine(LineST[i], tBusName, OUT_GEN_Para[0], OUT_GEN_Loca[0]);
				GetItemFromLine(LineST[i], &tBaseKV, OUT_GEN_Para[1], OUT_GEN_Loca[1]);
				equipno = BPABusSearch(tBusName, tBaseKV);
				AddNewBusDyn(equipno);
				flag = m_BusDyn[equipno]->ReadOutLine(LineST[i]);
				if (flag != 1)
				{
					sprintf(ErrorMessage[0], "输出数据读取失败:%s", Line);
					cpGetErrorInfo()->PrintWarning(11, 1);
				}
			}
		}
		if (flag == 1)IsRead[i] = 1;
	}
#ifdef _DEBUG
	for (i = 0; i < LineTotal; i++)
	{
		if (IsRead[i]>0)continue;
		sprintf(ErrorMessage[0], "  不能识别的数据卡:%s", LineST[i]);
		cpGetErrorInfo()->PrintWarning(8, 1);
	}
#endif
	free(LineST); FreeArray(IsRead);
	cpGetErrorInfo()->CheckMessageType(8);
	return 1;
}
void StitchImage( int height , int samples , const SphericalStencilTable< double >* stencilTable , StreamingGrid* in , StreamingGrid* labels , StreamingGrid* out , int iters , double iWeight , double gScale , double gWeight , const LabelType* unknownIndex )
{
	int width = height*2;
	StreamingNonAdaptiveLaplacian< Real , Channels , 3 , Real , LabelType > streamingLaplacian;
	StreamingAdaptiveNonAdaptiveConverter< Real , Channels > streamingConverter;

	streamingLaplacian.pixels = in;
	streamingLaplacian.labels = labels;
	streamingLaplacian.Initialize( width , height , samples , stencilTable , unknownIndex , iWeight , gScale*gWeight );
	streamingConverter.Initialize( height );

	const int Dim = Channels;
	int idx , fullDepth = 0 , outOfCoreDepth = 0 , inCoreDepth;
	while( 	!( (width>>fullDepth)&3 ) && !( (height>>fullDepth)&1 ) && (width>>fullDepth)>=MinRes.value && (height>>fullDepth)>=MinRes.value ) fullDepth++;
	int lowHeight = height>>fullDepth;
	int lowWidth = lowHeight * 2;
	fullDepth++;
	while( 	!( (width>>outOfCoreDepth)&3 ) && !( (height>>outOfCoreDepth)&1 ) && (width>>outOfCoreDepth)>=InCoreRes.value && (height>>outOfCoreDepth)>=InCoreRes.value ) outOfCoreDepth++;
	int midHeight = height>>outOfCoreDepth;
	int midWidth = midHeight * 2;
	outOfCoreDepth++;
	// WARNING: We are duplicating the solve on the liminal row
	inCoreDepth = fullDepth - outOfCoreDepth + 1;

	double t = Time();
	MultiStreamIOClient *fullXStream = NULL , *fullBStream = NULL;
	Pointer( Real ) midX = AllocArray< Real >( midWidth * midHeight * Dim );
	Pointer( Real ) midB = AllocArray< Real >( midWidth * midHeight * Dim );
	Pointer( Real ) lowB = AllocArray< Real >( lowWidth * lowHeight * Dim );
	Pointer( Real ) lowX = AllocArray< Real >( lowWidth * lowHeight * Dim );

	memset( lowX , 0 , sizeof( Real ) * lowWidth * lowHeight * Dim );
	memset( lowB , 0 , sizeof( Real ) * lowWidth * lowHeight * Dim );
	if( VCycles.value>1 )
	{
		fullXStream = new MultiStreamIOClient( width * Dim * sizeof( Real ) , height , STREAMING_GRID_BUFFER_MULTIPLIER , NULL , true );
		fullBStream = new MultiStreamIOClient( width * Dim * sizeof( Real ) , height , STREAMING_GRID_BUFFER_MULTIPLIER , NULL , true );
	}

	MemoryBackedGrid midXStream( ( Pointer( byte ) )midX , midWidth * sizeof( Real ) * Dim , midHeight , true );
	MemoryBackedGrid midBStream( ( Pointer( byte ) )midB , midWidth * sizeof( Real ) * Dim , midHeight , true );
	MemoryBackedGrid lowBStream( ( Pointer( byte ) )lowB , lowWidth * sizeof( Real ) * Dim , lowHeight , true );
	MemoryBackedGrid lowXStream( ( Pointer( byte ) )lowX , lowWidth * sizeof( Real ) * Dim , lowHeight , true );

	if( Verbose.set ) printf( "Set up time: %f\n" , Time() - t );

	MultiGridSphericalStreamingSolver< Real , IOReal > *inCoreSolvers , *outOfCoreSolvers;
	inCoreSolvers    = new MultiGridSphericalStreamingSolver< Real , IOReal >[    inCoreDepth ];
	outOfCoreSolvers = new MultiGridSphericalStreamingSolver< Real , IOReal >[ outOfCoreDepth ];

	for( int d=1 ; d<inCoreDepth    ; d++ ) inCoreSolvers   [d].child = &inCoreSolvers   [d-1] , inCoreSolvers   [d-1].parent = &inCoreSolvers   [d];
	for( int d=1 ; d<outOfCoreDepth ; d++ ) outOfCoreSolvers[d].child = &outOfCoreSolvers[d-1] , outOfCoreSolvers[d-1].parent = &outOfCoreSolvers[d];

	streamingLaplacian.parent = &streamingConverter;
	streamingConverter.child = &streamingLaplacian;
	streamingConverter.parent = &outOfCoreSolvers[0];

	outOfCoreSolvers[0].Initialize( Dim ,    width ,    height , samples , stencilTable , iWeight , gWeight , true );
	inCoreSolvers   [0].Initialize( Dim , midWidth , midHeight , samples , stencilTable , iWeight , gWeight , false );

	for( int v=0 ; v<VCycles.value ; v++ )
	{
		double vTime = Time();
		/////////////////
		// Restriction //
		/////////////////

		/////////////////
		// Out-of-Core //
		/////////////////
		t = Time();
		for( int d=0 ; d<outOfCoreDepth ; d++ )
		{
			for( int c=0 ; c<Dim ; c++ ) outOfCoreSolvers[d].bSquareNorm[c] = outOfCoreSolvers[d].rSquareNorm[c] = outOfCoreSolvers[d].xSquareNorm[c] = 0;
			outOfCoreSolvers[d].setResidual = true;
			outOfCoreSolvers[d].inX = outOfCoreSolvers[d].inB = outOfCoreSolvers[d].outX = outOfCoreSolvers[d].outB = NULL;
		}
		if( v )
		{
			outOfCoreSolvers[0].inX = fullXStream;
			outOfCoreSolvers[0].inB = fullBStream;
			outOfCoreSolvers[0].child = NULL;
		}
		else outOfCoreSolvers[0].child = &streamingConverter;

		outOfCoreSolvers[outOfCoreDepth-1].outB = &midBStream;
		outOfCoreSolvers[outOfCoreDepth-1].outX = &midXStream;

		if( !v )
		{
			( ( MultiGridRestrictionNode< Real >* )&streamingLaplacian )->InitRestriction( Progress.set );
			streamingLaplacian.SetRestrictionIterations( Iters.value );
			streamingLaplacian.SolveRestriction( );
		}
		else
		{
			( ( MultiGridRestrictionNode< Real >* ) outOfCoreSolvers )->InitRestriction( Progress.set );
			outOfCoreSolvers[0].SetRestrictionIterations( Iters.value );
			outOfCoreSolvers[0].SolveRestriction( );
		}

		if( Verbose.set )
		{
			printf( "Out-of-Core Restriction Time: %f\n" , Time() - t );
			for( int d=0 ; d<outOfCoreDepth ; d++ )
			{
				double bSquareNorm = 0 , rSquareNorm = 0;
				for( int c=0 ; c<Dim ; c++ ) bSquareNorm += outOfCoreSolvers[d].bSquareNorm[c] , rSquareNorm += outOfCoreSolvers[d].rSquareNorm[c];
				printf( "\tError[%d x %d]:\t%13.10f -> %13.10f\t%g\n" ,	outOfCoreSolvers[d].columns , outOfCoreSolvers[d].rows , sqrt( bSquareNorm ) , sqrt( rSquareNorm ) , sqrt( rSquareNorm/bSquareNorm ) );
			}
		}


		/////////////
		// In-Core //
		/////////////
		t = Time();
		for( int d=0 ; d<inCoreDepth ; d++ )
		{
			for( int c=0 ; c<Dim ; c++ ) inCoreSolvers[d].bSquareNorm[c] = inCoreSolvers[d].rSquareNorm[c] = inCoreSolvers[d].xSquareNorm[c] = 0;
			inCoreSolvers[d].setResidual = true;
			inCoreSolvers[d].inX = inCoreSolvers[d].inB = inCoreSolvers[d].outX = inCoreSolvers[d].outB = NULL;
		}

		inCoreSolvers[0].inX = &midXStream;
		inCoreSolvers[0].inB = &midBStream;

		inCoreSolvers[inCoreDepth-1].outB = &lowBStream;
		inCoreSolvers[inCoreDepth-1].outX = &lowXStream;

		inCoreSolvers[0].InitRestriction( );
		inCoreSolvers[0].SetRestrictionIterations( Iters.value );
		inCoreSolvers[0].SolveRestriction( );

		if( Verbose.set )
		{
			printf( "In-Core Restriction Time: %f\n" , Time() - t );
			for( int d=0 ; d<inCoreDepth ; d++ )
			{
				double bSquareNorm = 0 , rSquareNorm = 0;
				for( int c=0 ; c<Dim ; c++ ) bSquareNorm += inCoreSolvers[d].bSquareNorm[c] , rSquareNorm += inCoreSolvers[d].rSquareNorm[c];
				printf( "\tError[%d x %d]:\t%13.10f -> %13.10f\t%g\n" ,	inCoreSolvers[d].columns , inCoreSolvers[d].rows , sqrt( bSquareNorm ) , sqrt( rSquareNorm ) , sqrt( rSquareNorm/bSquareNorm ) );
			}
		}

		///////////////
		// CG-Solver //
		///////////////
		{
			t = Time();
			AdaptiveEquiRectangular< double > lowSphere( lowHeight , samples , stencilTable );
			SparseMatrix< double > laplacian;
			Vector< double > xx[Dim] , bb[Dim];
			for( int c=0 ; c<Dim ; c++ )
			{
				xx[c].Resize( lowSphere.dimension() );
				bb[c].Resize( lowSphere.dimension() );
			}
			// Get the constraint and solution vectors
			idx = 0;
			for( int j=0 ; j<lowHeight ; j++ )
			{
				for( int i=0 ; i<lowSphere.dimension( j ) ; i++ )
				{
					for( int c=0 ; c<Dim ; c++ )
					{
						bb[c][ idx ] = lowB[ lowWidth*Dim*j + lowWidth*c + i ];
						xx[c][ idx ] = lowX[ lowWidth*Dim*j + lowWidth*c + i ];
					}
					idx++;
				}
			}

			// Get the Laplacian matrix
			lowSphere.laplacianMatrix( laplacian , iWeight , gWeight );
			double bSquareNorm = 0 , rSquareNorm = 0;
			for( int c=0 ; c<Dim ; c++ )
			{
				bSquareNorm += ( bb[c]-laplacian*xx[c] ).SquareNorm();
				SolveConjugateGradient( laplacian , bb[c] , 6*int( sqrt( laplacian.groups + 1.0 ) ) , xx[c] , iWeight==0 );
				rSquareNorm += ( bb[c]-laplacian*xx[c] ).SquareNorm();
			}
			if( Verbose.set )
			{
				printf( "\tError[%d x %d]:\t%13.10f -> %13.10f\t%g\n" ,	lowWidth , lowHeight , sqrt( bSquareNorm ) , sqrt( rSquareNorm ) , sqrt( rSquareNorm/bSquareNorm ) );
				printf( "Conjugate-Gradient Time: %f\n" , Time() - t );
			}

			// Set the solution vectors
			idx = 0;
			for( int j=0 ; j<lowHeight ; j++ )
			{
				for( int i=0 ; i<lowSphere.dimension(j) ; i++ )
				{
					for( int c=0 ; c<Dim ; c++ ) lowX[ lowWidth*Dim*j + lowWidth*c + i ] = xx[c][ idx ];
					idx++;
				}
			}
		}

		//////////////////
		// Prolongation //
		//////////////////

		/////////////
		// In-Core //
		/////////////

		t = Time();
		for( int d=0 ; d<inCoreDepth ; d++ )
		{
			for( int c=0 ; c<Dim ; c++ ) inCoreSolvers[d].bSquareNorm[c] = inCoreSolvers[d].rSquareNorm[c] = inCoreSolvers[d].xSquareNorm[c] = 0;
			inCoreSolvers[d].inX = inCoreSolvers[d].inB = inCoreSolvers[d].outX = inCoreSolvers[d].outB = NULL;
		}
		inCoreSolvers[inCoreDepth-1].inX = &lowXStream;
		inCoreSolvers[0].outX = &midXStream;
		inCoreSolvers[0].outB = &midBStream;

		inCoreSolvers[0].InitProlongation( );
		inCoreSolvers[inCoreDepth-1].SetProlongationIterations( Iters.value );
		inCoreSolvers[inCoreDepth-1].SolveProlongation( );

		if( Verbose.set )
		{
			for( int d=inCoreDepth-1 ; d>=0 ; d-- )
			{
				double bSquareNorm = 0 , rSquareNorm = 0;
				for( int c=0 ; c<Dim ; c++ ) bSquareNorm += inCoreSolvers[d].bSquareNorm[c] , rSquareNorm += inCoreSolvers[d].rSquareNorm[c];
				printf( "\tError[%d x %d]:\t%13.10f -> %13.10f\t%g\n" ,	inCoreSolvers[d].columns , inCoreSolvers[d].rows , sqrt( bSquareNorm ) , sqrt( rSquareNorm ) , sqrt( rSquareNorm/bSquareNorm ) );
			}
			printf( "In-Core Prolongation Time: %f\n" , Time() - t );
		}

		if( v==VCycles.value-1 && iWeight==0 )
		{
			AdaptiveEquiRectangular< double > midSphere( midHeight , samples , stencilTable );
			Vector< double > weights;
			midSphere.elementWeights( weights );
			for( int c=0 ; c<Dim ; c++ )
			{
				double average = 0;
				idx = 0;
				for( int y=0 ; y<midHeight ; y++ ) for( int x=0 ; x<midSphere.dimension( y ) ; x++ ) average += midX[ y*midWidth*Dim + c*midWidth + x ] * weights[idx++];
				average /= 4. * M_PI;
				for( int y=0 ; y<midHeight ; y++ ) for( int x=0 ; x<midSphere.dimension( y ) ; x++ )  midX[ y*midWidth*Dim + c*midWidth + x ] += streamingLaplacian.average[c]-average;
			}
		}

		/////////////////
		// Out-of-Core //
		/////////////////

		t = Time();
		for( int d=0 ; d<outOfCoreDepth ; d++ )
		{
			for( int c=0 ; c<Dim ; c++ ) outOfCoreSolvers[d].bSquareNorm[c] = outOfCoreSolvers[d].rSquareNorm[c] = outOfCoreSolvers[d].xSquareNorm[c] = 0;
			outOfCoreSolvers[d].inX = outOfCoreSolvers[d].inB = outOfCoreSolvers[d].outX = outOfCoreSolvers[d].outB = NULL;
		}
		outOfCoreSolvers[outOfCoreDepth-1].inX = &midXStream;

		if( v==VCycles.value-1 )
		{
			streamingConverter.child = NULL;
			streamingConverter.outX = out;

			outOfCoreSolvers[0].outX = NULL;
			outOfCoreSolvers[0].outB = NULL;
			outOfCoreSolvers[0].child = &streamingConverter;
			( ( MultiGridRestrictionNode< Real >* )&streamingConverter )->InitProlongation( Progress.set );
		}
		else
		{
			outOfCoreSolvers[0].outX = fullXStream;
			outOfCoreSolvers[0].outB = fullBStream;
			outOfCoreSolvers[0].child = NULL;
			( ( MultiGridRestrictionNode< Real >* )outOfCoreSolvers )->InitProlongation( Progress.set );
		}
		outOfCoreSolvers[outOfCoreDepth-1].SetProlongationIterations( Iters.value );
		outOfCoreSolvers[outOfCoreDepth-1].SolveProlongation();

		if( Verbose.set )
		{
			for( int d=outOfCoreDepth-1 ; d>=0 ; d-- )
			{
				double bSquareNorm = 0 , rSquareNorm = 0;
				for( int c=0 ; c<Dim ; c++ ) bSquareNorm += outOfCoreSolvers[d].bSquareNorm[c] , rSquareNorm += outOfCoreSolvers[d].rSquareNorm[c];
				printf( "\tError[%d x %d]:\t%13.10f\t%g -> %13.10f\n" ,	outOfCoreSolvers[d].columns , outOfCoreSolvers[d].rows , sqrt( bSquareNorm ) , sqrt( rSquareNorm ) , sqrt( rSquareNorm/bSquareNorm ) );
			}
			printf( "Out-of-Core Prolongation Time: %f\n" , Time() - t );
			printf( "V-Cycle Time: %f\n" , Time( ) - vTime );
		}
	}
	delete[] inCoreSolvers;
	delete[] outOfCoreSolvers;
	if( fullXStream ) delete fullXStream;
	if( fullBStream ) delete fullBStream;
	FreeArray( midX );
	FreeArray( midB );
	FreeArray( lowB );
	FreeArray( lowX );
}
Пример #29
0
/* 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. */
}
Пример #30
0
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 );
}