📄 spbuild.c
字号:
else break; /* while loop */ }/* Element does not exist and must be created. */ if (CreateIfMissing) return spcCreateElement( Matrix, Row, Col, LastAddr, NO ); else return NULL;}#if TRANSLATE/* * TRANSLATE EXTERNAL INDICES TO INTERNAL * * Convert external row and column numbers to internal row and column numbers. * Also updates Ext/Int maps. * * * >>> Arguments: * Matrix <input> (MatrixPtr) * Pointer to the matrix. * Row <input/output> (int *) * Upon entry Row is either a external row number or an external node * number. Upon return, the internal equivalent is supplied. * Col <input/output> (int *) * Upon entry Column is either a external column number or an external node * number. Upon return, the internal equivalent is supplied. * * >>> Local variables: * ExtCol (int) * Temporary variable used to hold the external column or node number * during the external to internal column number translation. * ExtRow (int) * Temporary variable used to hold the external row or node number during * the external to internal row number translation. * IntCol (int) * Temporary variable used to hold the internal column or node number * during the external to internal column number translation. * IntRow (int) * Temporary variable used to hold the internal row or node number during * the external to internal row number translation. */static voidTranslate( Matrix, Row, Col )MatrixPtr Matrix;int *Row, *Col;{register int IntRow, IntCol, ExtRow, ExtCol;/* Begin `Translate'. */ ExtRow = *Row; ExtCol = *Col;/* Expand translation arrays if necessary. */ if ((ExtRow > Matrix->AllocatedExtSize) OR (ExtCol > Matrix->AllocatedExtSize)) { ExpandTranslationArrays( Matrix, MAX(ExtRow, ExtCol) ); if (Matrix->Error == spNO_MEMORY) return; }/* Set ExtSize if necessary. */ if ((ExtRow > Matrix->ExtSize) OR (ExtCol > Matrix->ExtSize)) Matrix->ExtSize = MAX(ExtRow, ExtCol);/* Translate external row or node number to internal row or node number. */ if ((IntRow = Matrix->ExtToIntRowMap[ExtRow]) == -1) { Matrix->ExtToIntRowMap[ExtRow] = ++Matrix->CurrentSize; Matrix->ExtToIntColMap[ExtRow] = Matrix->CurrentSize; IntRow = Matrix->CurrentSize;#if NOT EXPANDABLE ASSERT(IntRow <= Matrix->Size);#endif#if EXPANDABLE/* Re-size Matrix if necessary. */ if (IntRow > Matrix->Size) EnlargeMatrix( Matrix, IntRow ); if (Matrix->Error == spNO_MEMORY) return;#endif Matrix->IntToExtRowMap[IntRow] = ExtRow; Matrix->IntToExtColMap[IntRow] = ExtRow; }/* Translate external column or node number to internal column or node number.*/ if ((IntCol = Matrix->ExtToIntColMap[ExtCol]) == -1) { Matrix->ExtToIntRowMap[ExtCol] = ++Matrix->CurrentSize; Matrix->ExtToIntColMap[ExtCol] = Matrix->CurrentSize; IntCol = Matrix->CurrentSize;#if NOT EXPANDABLE ASSERT(IntCol <= Matrix->Size);#endif#if EXPANDABLE/* Re-size Matrix if necessary. */ if (IntCol > Matrix->Size) EnlargeMatrix( Matrix, IntCol ); if (Matrix->Error == spNO_MEMORY) return;#endif Matrix->IntToExtRowMap[IntCol] = ExtCol; Matrix->IntToExtColMap[IntCol] = ExtCol; } *Row = IntRow; *Col = IntCol; return;}#endif#if QUAD_ELEMENT/* * ADDITION OF ADMITTANCE TO MATRIX BY INDEX * * Performs same function as spGetElement except rather than one * element, all four Matrix elements for a floating component are * added. This routine also works if component is grounded. Positive * elements are placed at [Node1,Node2] and [Node2,Node1]. This * routine is only to be used after spCreate() and before * spMNA_Preorder(), spFactor() or spOrderAndFactor(). * * >>> Returns: * Error code. * * >>> Arguments: * Matrix <input> (char *) * Pointer to the matrix that component is to be entered in. * Node1 <input> (int) * Row and column indices for elements. Must be in the range of [0..Size] * unless the options EXPANDABLE or TRANSLATE are used. Node zero is the * ground node. In no case may Node1 be less than zero. * Node2 <input> (int) * Row and column indices for elements. Must be in the range of [0..Size] * unless the options EXPANDABLE or TRANSLATE are used. Node zero is the * ground node. In no case may Node2 be less than zero. * Template <output> (struct spTemplate *) * Collection of pointers to four elements that are later used to directly * address elements. User must supply the template, this routine will * fill it. * * Possible errors: * spNO_MEMORY * Error is not cleared in this routine. */intspGetAdmittance( Matrix, Node1, Node2, Template )char *Matrix;int Node1, Node2;struct spTemplate *Template;{/* Begin `spGetAdmittance'. */ Template->Element1 = spGetElement(Matrix, Node1, Node1 ); Template->Element2 = spGetElement(Matrix, Node2, Node2 ); Template->Element3Negated = spGetElement( Matrix, Node2, Node1 ); Template->Element4Negated = spGetElement( Matrix, Node1, Node2 ); if ( (Template->Element1 == NULL) OR (Template->Element2 == NULL) OR (Template->Element3Negated == NULL) OR (Template->Element4Negated == NULL) ) return spNO_MEMORY; if (Node1 == 0) SWAP( RealNumber*, Template->Element1, Template->Element2 ); return spOKAY;}#endif /* QUAD_ELEMENT */#if QUAD_ELEMENT/* * ADDITION OF FOUR ELEMENTS TO MATRIX BY INDEX * * Similar to spGetAdmittance, except that spGetAdmittance only * handles 2-terminal components, whereas spGetQuad handles simple * 4-terminals as well. These 4-terminals are simply generalized * 2-terminals with the option of having the sense terminals different * from the source and sink terminals. spGetQuad adds four * elements to the matrix. Positive elements occur at Row1,Col1 * Row2,Col2 while negative elements occur at Row1,Col2 and Row2,Col1. * The routine works fine if any of the rows and columns are zero. * This routine is only to be used after spCreate() and before * spMNA_Preorder(), spFactor() or spOrderAndFactor() * unless TRANSLATE is set true. * * >>> Returns: * Error code. * * >>> Arguments: * Matrix <input> (char *) * Pointer to the matrix that component is to be entered in. * Row1 <input> (int) * First row index for elements. Must be in the range of [0..Size] * unless the options EXPANDABLE or TRANSLATE are used. Zero is the * ground row. In no case may Row1 be less than zero. * Row2 <input> (int) * Second row index for elements. Must be in the range of [0..Size] * unless the options EXPANDABLE or TRANSLATE are used. Zero is the * ground row. In no case may Row2 be less than zero. * Col1 <input> (int) * First column index for elements. Must be in the range of [0..Size] * unless the options EXPANDABLE or TRANSLATE are used. Zero is the * ground column. In no case may Col1 be less than zero. * Col2 <input> (int) * Second column index for elements. Must be in the range of [0..Size] * unless the options EXPANDABLE or TRANSLATE are used. Zero is the * ground column. In no case may Col2 be less than zero. * Template <output> (struct spTemplate *) * Collection of pointers to four elements that are later used to directly * address elements. User must supply the template, this routine will * fill it. * Real <input> (RealNumber) * Real data to be added to elements. * Imag <input> (RealNumber) * Imag data to be added to elements. If matrix is real, this argument * may be deleted. * * Possible errors: * spNO_MEMORY * Error is not cleared in this routine. */intspGetQuad( Matrix, Row1, Row2, Col1, Col2, Template )char *Matrix;int Row1, Row2, Col1, Col2;struct spTemplate *Template;{/* Begin `spGetQuad'. */ Template->Element1 = spGetElement( Matrix, Row1, Col1); Template->Element2 = spGetElement( Matrix, Row2, Col2 ); Template->Element3Negated = spGetElement( Matrix, Row2, Col1 ); Template->Element4Negated = spGetElement( Matrix, Row1, Col2 ); if ( (Template->Element1 == NULL) OR (Template->Element2 == NULL) OR (Template->Element3Negated == NULL) OR (Template->Element4Negated == NULL) ) return spNO_MEMORY; if (Template->Element1 == &((MatrixPtr)Matrix)->TrashCan.Real) SWAP( RealNumber *, Template->Element1, Template->Element2 ); return spOKAY;}#endif /* QUAD_ELEMENT */#if QUAD_ELEMENT/* * ADDITION OF FOUR STRUCTURAL ONES TO MATRIX BY INDEX * * Performs similar function to spGetQuad() except this routine is * meant for components that do not have an admittance representation. * * The following stamp is used: * Pos Neg Eqn * Pos [ . . 1 ] * Neg [ . . -1 ] * Eqn [ 1 -1 . ] * * >>> Returns: * Error code. * * >>> Arguments: * Matrix <input> (char *) * Pointer to the matrix that component is to be entered in. * Pos <input> (int) * See stamp above. Must be in the range of [0..Size] * unless the options EXPANDABLE or TRANSLATE are used. Zero is the * ground row. In no case may Pos be less than zero. * Neg <input> (int) * See stamp above. Must be in the range of [0..Size] * unless the options EXPANDABLE or TRANSLATE are used. Zero is the * ground row. In no case may Neg be less than zero. * Eqn <input> (int) * See stamp above. Must be in the range of [0..Size] * unless the options EXPANDABLE or TRANSLATE are used. Zero is the * ground row. In no case may Eqn be less than zero. * Template <output> (struct spTemplate *) * Collection of pointers to four elements that are later used to directly * address elements. User must supply the template, this routine will * fill it. * * Possible errors: * spNO_MEMORY * Error is not cleared in this routine. */intspGetOnes(Matrix, Pos, Neg, Eqn, Template)char *Matrix;int Pos, Neg, Eqn;struct spTemplate *Template;{/* Begin `spGetOnes'. */ Template->Element4Negated = spGetElement( Matrix, Neg, Eqn ); Template->Element3Negated = spGetElement( Matrix, Eqn, Neg ); Template->Element2 = spGetElement( Matrix, Pos, Eqn ); Template->Element1 = spGetElement( Matrix, Eqn, Pos ); if ( (Template->Element1 == NULL) OR (Template->Element2 == NULL) OR (Template->Element3Negated == NULL) OR (Template->Element4Negated == NULL) ) return spNO_MEMORY; spADD_REAL_QUAD( *Template, 1.0 ); return spOKAY;}#endif /* QUAD_ELEMENT *//* * * CREATE AND SPLICE ELEMENT INTO MATRIX * * This routine is used to create new matrix elements and splice them into the * matrix. * * >>> Returned: * A pointer to the element that was created is returned. * * >>> Arguments: * Matrix <input> (MatrixPtr) * Pointer to matrix. * Row <input> (int) * Row index for element. * Col <input> (int) * Column index for element. * LastAddr <input-output> (ElementPtr *) * This contains the address of the pointer to the element just above the * one being created. It is used to speed the search and it is updated with * address of the created element. * Fillin <input> (BOOLEAN) * Flag that indicates if created element is to be a fill-in. * * >>> Local variables: * pElement (ElementPtr) * Pointer to an element in the matrix. It is used to refer to the newly * created element and to restring the pointers of the element's row and * column. * pLastElement (ElementPtr) * Pointer to the element in the matrix that was just previously pointed * to by pElement. It is used to restring the pointers of the element's * row and column. * pCreatedElement (ElementPtr) * Pointer to the desired element, the one that was just created. * * >>> Possible errors: * spNO_MEMORY */ElementPtrspcCreateElement( Matrix, Row, Col, LastAddr, Fillin )MatrixPtr Matrix;int Row;register int Col;register ElementPtr *LastAddr;BOOLEAN Fillin;{register ElementPtr pElement, pLastElement;ElementPtr pCreatedElement, spcGetElement(), spcGetFillin();/* Begin `spcCreateElement'. */ if (Matrix->RowsLinked) {/* Row pointers cannot be ignored. */ if (Fillin) { pElement = spcGetFillin( Matrix ); Matrix->Fillins++; } else { pElement = spcGetElement( Matrix ); Matrix->Originals++; Matrix->NeedsOrdering = YES; } if (pElement == NULL) return NULL;/* If element is on diagonal, store pointer in Diag. */ if (Row == Col) Matrix->Diag[Row] = pElement;/* Initialize Element. */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -