This repository serve as a backup for my Maxwell-TD code
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

451 lines
8.5 KiB

#include <iostream>
#include <fstream>
#include <iomanip>
#include "matconv.h"
#include "sparmat.h"
using namespace std;
matlist::matlist()
{
col = -1;
next = 0;
}
void matlist::print()
{
cout << "col = " << col;
}
list2::list2()
{
next = 0;
matListPtr = 0;
}
matconv::matconv()
{
dim = 0;
NZ = 0;
newMem = 0;
matDiag = 0;
type = SYMMETRIC;
allocPos = new list2;
tmpList2 = allocPos;
}
matconv::~matconv()
{
deleteMemory();
}
void matconv::deleteMemory()
{
list2* nextPtr = NULL;
tmpList2 = allocPos;
while (tmpList2->next != 0) {
delete [] tmpList2->matListPtr;
nextPtr = tmpList2->next;
delete tmpList2;
tmpList2 = nextPtr;
}
delete tmpList2;
delete [] matDiag;
}
void matconv::setDim(int n)
{
int i;
dim = n;
NZ = n;
matDiag = new matlist[n];
for (i = 0; i < dim; i++) {
matDiag[i].col = i;
if (i != (dim - 1)) matDiag[i].next = &(matDiag[i + 1]);
}
}
void matconv::setNsDim(int n)
{
int i;
dim = n;
matDiag = new matlist[n];
for (i = 0; i < dim; i ++) {
matDiag[i].col = -1;
matDiag[i].next = 0;
}
type = NON_SYMMETRIC;
}
void matconv::init(int n)
{
int i;
dim = n;
NZ = n;
matDiag = new matlist[n];
if (type != NON_SYMMETRIC) {
for (i = 0; i < dim; i ++) {
matDiag[i].col = i;
matDiag[i].next = 0;
}
} else {
for (i = 0; i < dim; i ++) {
matDiag[i].col = 0;
matDiag[i].next = 0;
}
}
}
void matconv::addentry(int r, int c)
{
matlist *pEntry, *cEntry;
// only store the upper half of the matrix
if (r < 0 || c < 0) return;
if (c < r) return;
if (r == c) return;
if (r == (dim - 1)) return;
pEntry = &(matDiag[r]);
cEntry = pEntry->next;
while (cEntry != &(matDiag[r + 1])) {
if (cEntry->col > c) {
if (newMem == 0) blockMemory(dim);
pEntry->next = newMem;
newMem = newMem->next;
pEntry = pEntry->next;
pEntry->col = c;
pEntry->next = cEntry;
NZ++;
return;
}
if (cEntry->col == c) return;
pEntry = cEntry;
cEntry = cEntry->next;
}
if (newMem == 0) blockMemory(dim);
pEntry->next = newMem;
newMem = newMem->next;
pEntry = pEntry->next;
pEntry->col = c;
pEntry->next = cEntry;
NZ++;
}
void matconv::addNsEntry(int r, int c)
{
matlist *pEntry, *cEntry;
// only store the upper half of the matrix
if (r < 0 || c < 0) return;
pEntry = &(matDiag[r]);
cEntry = pEntry->next;
while (cEntry != 0) {
if (cEntry->col > c) {
if (newMem == 0) blockMemory(dim);
pEntry->next = newMem;
newMem = newMem->next;
pEntry = pEntry->next;
pEntry->col = c;
pEntry->next = cEntry;
NZ ++;
return;
}
if (cEntry->col == c) return;
pEntry = cEntry;
cEntry = cEntry->next;
}
if (newMem == 0) blockMemory(dim);
pEntry->next = newMem;
newMem = newMem->next;
pEntry = pEntry->next;
pEntry->col = c;
pEntry->next = cEntry;
NZ ++;
}
void matconv::blockMemory(int n)
{
int i;
matlist *bMem;
bMem = new matlist[n];
for (i = 0; i < n; i++) {
if (i != (n - 1)) bMem[i].next = &(bMem[i + 1]);
}
newMem = &(bMem[0]);
// added to keep track of the positions we add memery,
// in order to delete it correctly at the end
tmpList2->matListPtr = newMem;
tmpList2->next = new list2;
tmpList2 = tmpList2->next;
}
void matconv::conversion(sparMat *A)
{
int i, counter;
matlist *cEntry;
A->sparInit(dim, NZ);
counter = 0;
for (i = 0; i < (dim - 1); i++) {
A->setJA(counter, i);
A->setIA(i, counter);
counter++;
cEntry = matDiag[i].next;
while (cEntry != &(matDiag[i + 1])) {
A->setJA(counter, cEntry->col);
counter++;
cEntry = cEntry->next;
}
}
A->setJA(counter, dim - 1);
A->setIA(dim - 1, counter);
counter++;
A->setIA(dim, counter);
// cout << " NZ = " << NZ << ", COUNTER = " << counter << endl;
}
void matconv::blockAddEntry(int n, int *map)
{
int i, j, row, col;
for (i = 0; i < n; i++) {
row = map[i];
if (row < 0) continue;
if (row >= dim) {
cout << "ERROR: ID " << row << " is greater than " << dim
<< endl;
}
for (j = 0; j < n; j++) {
col = map[j];
if (col < 0) continue;
addentry(row, col);
}
}
}
void matconv::blockAddEntry(int n, int *rowMap, int *colMap)
{
int i, j, row, col;
for (i = 0; i < n; i++) {
row = rowMap[i];
if (row < 0) continue;
if (row >= dim) {
cout << "ERROR: ID " << row << " is greater than " << dim
<< endl;
}
for (j = 0; j < n; j++) {
col = colMap[j];
if (col < 0) continue;
addentry(row, col);
}
}
}
void matconv::blockAddEntry(int rowDim, int colDim, int *rowMap, int *colMap)
{
int i, j, row, col;
for (i = 0; i < rowDim; i ++) {
row = rowMap[i];
if (row < 0) continue;
if (row >= dim) {
cout << "ERROR: ID " << row << " is greater than " << dim << endl;
}
for (j = 0; j < colDim; j ++) {
col = colMap[j];
if (col < 0) continue;
if (type == NON_SYMMETRIC) addNsEntry(row, col);
else addentry(row, col);
}
}
}
void matconv::freeMemory(matlist *entry)
{
entry->col = -100;
entry->next = newMem;
newMem = entry;
}
void matconv::print()
{
int i;
matlist *curPtr;
cout << "MATCONV" << endl;
cout << "dim=" << dim << endl;
cout << "NZ=" << NZ << endl;
for (i = 0; i < dim; i++) {
cout << "matDiag[" << i << "]" << endl;
matDiag[i].print();
curPtr = &(matDiag[i]);
while(curPtr->next !=0) {
curPtr = curPtr->next;
curPtr->print();
}
}
}
void matconv::setDimNonSymm(int n)
{
int i;
dim = n;
NZ = n;
// matDiag = new matlist[n+1];
// for (i = 0; i < dim+1; i ++) {
// matDiag[i].col = 0;
// if (i != (dim - 1)) matDiag[i].next = &(matDiag[i + 1]);
// }
matDiag = new matlist[n+1];
for (i = 0; i < dim+1; i ++) {
matDiag[i].col = 0;
matDiag[i].next = 0;//&(matDiag[i + 1]);
}
}
void matconv::addentryNonSymm(int r, int c)
{
matlist *pEntry, *cEntry;
// store entire matrix
if (r < 0 || c < 0) return;
// if (c == 0) return;
// if (c < r) return;
// if (r == c) return;
// if (r == (dim - 1)) return;
pEntry = &(matDiag[r]);
cEntry = pEntry->next;
// while (cEntry != &(matDiag[r + 1])) {
while (cEntry != 0) {
if (cEntry->col > c) {
if (newMem == 0) blockMemory(dim);
pEntry->next = newMem;
newMem = newMem->next;
pEntry = pEntry->next;
pEntry->col = c;
pEntry->next = cEntry;
NZ ++;
return;
}
if (cEntry->col == c) return;
pEntry = cEntry;
cEntry = cEntry->next;
}
if (newMem == 0) blockMemory(dim);
pEntry->next = newMem;
newMem = newMem->next;
pEntry = pEntry->next;
pEntry->col = c;
pEntry->next = cEntry;
NZ ++;
}
void matconv::blockAddEntryNonSymm(int rowDim, int colDim,
int *rowMap, int *colMap)
{
int i, j, row, col;
for (i = 0; i < rowDim; i ++) {
row = rowMap[i];
if (row < 0) continue;
if (row >= dim) {
cout << "ERROR: ID " << row << " is greater than " << dim << endl;
}
for (j = 0; j < colDim; j ++) {
col = colMap[j];
if (col < 0) continue;
addentryNonSymm(row, col);
}
}
}
void matconv::conversionNonSymm(sparMat *A)
{
int i, counter;
matlist *cEntry;
// A->sparInit(dim, NZ);
A->sparInitNonSymm(dim, NZ);
counter = 0;
// for (i = 0; i < (dim - 1); i ++) {
for (i = 0; i < dim; i ++) {
A->setJA(counter, i);
A->setIA(i, counter);
counter ++;
cEntry = matDiag[i].next;
// while (cEntry != &(matDiag[i + 1])) {
while (cEntry != 0) {
A->setJA(counter, cEntry->col);
counter ++;
cEntry = cEntry->next;
}
}
// A->setJA(counter, dim - 1);
// A->setIA(dim - 1, counter);
// counter ++;
A->setIA(dim, counter);
// cout << " NZ = " << NZ << ", COUNTER = " << counter << endl;
}
void matconv::conversion(sparMat *A, int rowDim, int colDim)
{
int i, counter;
matlist *cEntry;
A->sparINIT(rowDim, colDim, NZ);
counter = 0;
for (i = 0; i < (dim); i ++) {
A->setIA(i, counter);
if (matDiag[i].next == 0) continue;
cEntry = matDiag[i].next;
while (cEntry->col >= 0) {
A->setJA(counter, cEntry->col);
counter ++;
if (cEntry->next == 0) break;
cEntry = cEntry->next;
}
}
if (NZ != counter) {
cout << "Error in non-symmetric conversion" << endl;
cout << " NZ = " << NZ << ", COUNTER = " << counter << endl;
exit(1);
}
cout << " NZ = " << NZ << ", COUNTER = " << counter << endl;
A->setIA(dim, counter);
}