/*
 $Id: triang3tr.cc,v 1.2 1996/10/08 08:17:44 roitzsch Exp $
 (C)opyright 1996 by Konrad-Zuse-Center, Berlin
 All rights reserved.
 Part of the Kaskade distribution
*/

#include "triang3tr.h"

#include "utils.h"
#include "numerics.h"

//-------------------------------------------------------------------------

const PATCH* MESH3:: findPatch(const Vector<Real>& x, Vector<Real>& xUnit,
			       const PATCH* /*newPatch*/) const 
{
    TET3* tet;
    for (tet=tetList[0]->first; tet; tet=tet->next)
    {
	if (tet->inPatch(x,xUnit)) return tet->findPatch(x,xUnit);
    }
    patchNotFound();
    return 0;
}
//-------------------------------------------------------------------------


const PATCH* TET3:: findPatch(const Vector<Real>& x, Vector<Real>& xUnit) const 
{
    int nTet=0, k;
    TET3* t;

    if (refined()) 
    {
	nTet = NoOfSons();
	t = firstSon;

	for (k=1; k<nTet; ++k) 
	{
	    if (t->inPatch(x,xUnit))  return t->findPatch(x,xUnit);
	    t = t->next;
	}
	return t->findPatch(x,xUnit);
    }
    else  
    {
	unitCoordinates(x,xUnit);
	return this;
    }
}
//-------------------------------------------------------------------------


Bool TET3:: inPatch(const Vector<Real>& x, Vector<Real>& xUnit) const 
{
    static const Real tiny = -1000*machPrec(Real(0.0));
    static const Real approx1 = 1.0 - tiny;

    unitCoordinates(x,xUnit);

    if (xUnit[1] < tiny)  return False;
    if (xUnit[2] < tiny)  return False;
    if (xUnit[3] < tiny)  return False;
    if (xUnit[1] + xUnit[2] + xUnit[3] > approx1)  return False;

    return True;
}
//-------------------------------------------------------------------------
//-------------------------------------------------------------------------


MESH3Trans:: MESH3Trans(const char* inFileName, MESH3* prevMesh0)

	: MESH3(inFileName,False), 
	  prevMesh(prevMesh0), tetTrAlloc(ElementsInBlock)
{
    readTriangulation(fileName);
    if (prevMesh) setInitialPartners(prevMesh);
}
//-------------------------------------------------------------------------


void MESH3Trans:: Refine()
{
    MESH3::Refine();
    if (prevMesh) setPartners();
}
//-------------------------------------------------------------------------


const PATCH* MESH3Trans:: findPatch(const Vector<Real>& x, Vector<Real>& xUnit,
				    const PATCH* newPatch) const
{
    return newPatch->Partner()->findPatch(x,xUnit);
}
//-------------------------------------------------------------------------

int  MESH3Trans:: MemSpace()
{
    int space = varAllocator.MemSpace();

    space += tetTrAlloc.MemSpace();
    space += edgAlloc.MemSpace();
    space += ptAlloc.MemSpace();
  
    space += trList[0]->first->alloc.MemSpace();

    return space;
}
//-------------------------------------------------------------------------


