/*
$Id: familyA.cc,v 1.2 1996/11/20 09:57:25 roitzsch Exp $
(C)opyright 1996 by Konrad-Zuse-Center, Berlin
All rights reserved.
Part of the Kaskade distribution
*/
#include "familyA.h"
#include "utils.h"
//-------------------------------------------------------------------------
StaticAllocator<PointSon> PointSon:: alloc(ElementsInBlock);
StaticAllocator<EdgeSon> EdgeSon:: alloc(ElementsInBlock);
//-------------------------------------------------------------------------
//-------------------------------------------------------------------------
MCGeneration:: MCGeneration(int noOfNodes, int nComp0)
: Generation(noOfNodes/nComp0), nComp(nComp0)
{ }
//-------------------------------------------------------------------------
void MCGeneration:: extend(int noOfNodes)
{
Generation::extend(noOfNodes/nComp);
}
//-------------------------------------------------------------------------
void MCGeneration:: insertSon(int node, Son* newSon)
{
int block = MCNode.block(node, nComp);
son[block] = newSon;
}
//-------------------------------------------------------------------------
Son* MCGeneration:: getSon(int block) const
{
//block = MCNode.baseNode(node, nComp);
return son[block];
}
//-------------------------------------------------------------------------
void MCGeneration:: prolong(const Vector<Num>& el, Vector<Num>& eh) const
{
int i, node = 1;
FORALL(son,i)
{
son[i]->prolong(el, eh, node, nComp);
node += nComp;
}
}
//-------------------------------------------------------------------------
void MCGeneration:: restr(Vector<Num>& rh, Vector<Num>& rl) const
{
int i, node = 1;
FORALL(rl,i) rl[i] = 0.0;
FORALL(son,i)
{
son[i]->restr(rh, rl, node, nComp);
node += nComp;
}
}
//-------------------------------------------------------------------------
//-------------------------------------------------------------------------
void MCGeneration:: solToNB(Vector<Num>& e) const
{
int i, node = 1;
FORALL(son,i)
{
son[i]->prolong(e, e, node, nComp);
node += nComp;
}
}
//-------------------------------------------------------------------------
void MCGeneration:: rhsToHB(Vector<Num>& r) const
{
int i, node = 1;
FORALL(son,i)
{
son[i]->restr(r, r, node, nComp);
node += nComp;
}
}
//-------------------------------------------------------------------------
//-------------------------------------------------------------------------
LinEdgeGeneration:: LinEdgeGeneration(int low, int high) : Generation(1)
{
fathers = new Matrix<int>(1,2,low,high);
}
LinEdgeGeneration:: ~LinEdgeGeneration() { delete fathers; }
//-------------------------------------------------------------------------
void LinEdgeGeneration:: prolong(const Vector<Num>& el, Vector<Num>& eh) const
{
int i, n, fatherNode;
const int low = fathers->cl;
for (i=1; i<low; ++i) eh[i] += el[i]; // point nodes
FORALL_COLUMNS(*fathers,i)
{
for (n=1; n<=2; ++n)
{
fatherNode = (*fathers)(n,i);
if (fatherNode > low) eh[i] += 0.5 * eh[fatherNode];
else eh[i] += 0.5 * el[fatherNode];
}
}
// the case (fatherNode > low) may occur with refinement by bisection!
}
//-------------------------------------------------------------------------
void LinEdgeGeneration:: restr(Vector<Num>& rh, Vector<Num>& rl) const
{
int i, n, fatherNode;
const int low = fathers->cl;
for (i=1; i<low; ++i) rl[i] = rh[i];
for (i=fathers->ch; i>=low; --i)
{
for (n=1; n<=2; ++n)
{
fatherNode = (*fathers)(n,i);
if (fatherNode > low) rh[fatherNode] += 0.5 * rh[i];
else rl[fatherNode] += 0.5 * rh[i];
}
}
// the case (fatherNode > low) may occur with refinement by bisection!
}
//-------------------------------------------------------------------------
// Hierarchical basis transfer operations P and P**T:
void LinEdgeGeneration:: solToNB(Vector<Num>& e) const
{
int i;
FORALL_COLUMNS(*fathers,i)
e[i] += 0.5* (e[(*fathers)(1,i)] + e[(*fathers)(2,i)]);
}
//-------------------------------------------------------------------------
void LinEdgeGeneration:: rhsToHB(Vector<Num>& r) const
{
int i;
for (i=fathers->ch; i>=fathers->cl; --i)
{
r[(*fathers)(1,i)] += 0.5*r[i];
r[(*fathers)(2,i)] += 0.5*r[i];
}
}
//-------------------------------------------------------------------------
void LinEdgeGeneration:: setFathers(int father1, int father2, int node)
{
(*fathers)(1,node) = father1;
(*fathers)(2,node) = father2;
}
//-------------------------------------------------------------------------
void LinEdgeGeneration:: print() const
{
int i;
FORALL_COLUMNS(*fathers,i)
{
cout << " node " << i << " fathers: "
<< (*fathers)(1,i) << " " << (*fathers)(2,i) << "\n";
}
}
//-------------------------------------------------------------------------
//-------------------------------------------------------------------------
void PointSon:: prolong(const Vector<Num>& el, Vector<Num>& eh, int node,
int nComp) const
{
int n, f1 = father;
FORNCOMP(n) eh[node++] += el[f1++];
}
//-------------------------------------------------------------------------
void PointSon:: restr(Vector<Num>& rh, Vector<Num>& rl, int node,
int nComp) const
{
int n, f1 = father;
FORNCOMP(n) rl[f1++] += rh[node++];
}
//-------------------------------------------------------------------------
void PointSon:: print() const { cout << " father: " << father << "\n"; }
//-------------------------------------------------------------------------
//-------------------------------------------------------------------------
void EdgeSon:: prolong(const Vector<Num>& el, Vector<Num>& eh, int node,
int nComp) const
{
int n, f1 = father1, f2 = father2;
FORNCOMP(n) eh[node++] += 0.5*(el[f1++] + el[f2++]);
}
//-------------------------------------------------------------------------
void EdgeSon:: restr(Vector<Num>& rh, Vector<Num>& rl, int node,
int nComp) const
{
int n, f1 = father1, f2 = father2;
FORNCOMP(n)
{
rl[f1++] += 0.5 * rh[node];
rl[f2++] += 0.5 * rh[node];
++node;
}
}
//-------------------------------------------------------------------------
void EdgeSon:: print() const
{
cout << " fathers: " << father1 << " " << father2 << "\n";
}
//-------------------------------------------------------------------------
int EdgeSon:: getFather(int no) const
{
if (no == 1) return father1;
else if (no == 2) return father2;
else
{
cout << "\n*** EdgeSon::Father(int no): wrong number no ("
<< no << ") given\n";
cout.flush(); abort();
}
return 0;
}
//-------------------------------------------------------------------------
syntax highlighted by Code2HTML, v. 0.9.1