/*
 $Id: userTransient.cc,v 1.3 1996/11/19 09:46:21 bzferdma Exp $
 (C)opyright 1996 by Konrad-Zuse-Center, Berlin
 All rights reserved.
 Part of the Kaskade distribution
*/

#include "materialstr.h"
#include "dirichlettr.h"

#include "cmdpars.h"
extern CmdPars Cmd;

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

void UserTransMaterial:: setMaterialType()
{
    cout << "In UserTransMaterial::setMaterialType: isotropic" << endl;
    matType = isotropic;
}

Real UserTransMaterial:: E(int /*type*/, Vector<Real>* x, int /*i*/, int /*j*/)
{
    Vector<Real>& xx = *x;

    switch(spaceDim)
    {
      case 1: return E1d(xx[1]);
      case 2: return E2d(xx[1], xx[2]);
      case 3: return E3d(xx[1], xx[2], xx[3]);
      default: cout.flush(); abort(); return 0;
    }
}

Real UserTransMaterial:: E1d(Real x)
{
    return x;
}
    
Real UserTransMaterial:: E2d(Real /*x*/, Real /*y*/)
{
    return 1.0;
}

Real UserTransMaterial:: E3d(Real /*x*/, Real /*y*/, Real /*z*/)
{
    return 1.0;
}
//-------------------------------------------------------------------------


Real UserTransMaterial:: P(int /*type*/, Vector<Real>* x, int /*i*/, int /*j*/)
{
    Vector<Real>& xx = *x;

    switch(spaceDim)
    {
      case 1: return P1d(xx[1]);
      case 2: return P2d(xx[1], xx[2]);
      case 3: return P3d(xx[1], xx[2], xx[3]);
      default: cout.flush(); abort(); return 0;
    }
}

Real UserTransMaterial:: P1d(Real x)
{
    return x;
}
    
Real UserTransMaterial:: P2d(Real /*x*/, Real /*y*/)
{
    return 1.0;
}

Real UserTransMaterial:: P3d(Real /*x*/, Real /*y*/, Real /*z*/)
{
    return 1.0;
}


//-------------------------------------------------------------------------
Real UserTransMaterial:: M(int /*type*/, Vector<Real>* /*x*/, int /*i*/, int /*j*/)
{

    switch(spaceDim)
    {
      case 1: return 1.0;
      case 2: return 1.0;
      case 3: return 0.0;
      default: cout.flush(); abort(); return 0;
    }
}


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

Real UserTransMaterial:: S(int /*type*/, Vector<Real>* x, Real time)
{
    Vector<Real>& xx = *x;

    switch(spaceDim)
    {
      case 1: return S1d(xx[1], time);
      case 2: return S2d(xx[1], xx[2], time);
      case 3: return S3d(xx[1], xx[2], xx[3], time);
      default: cout.flush(); abort(); return 0;
    }
}

Real UserTransMaterial:: S1d(Real x, Real time)
{
    Real s = 0.0;
    s = (x*x - time - x*time*time + 1.)*exp(time * x);
    return s;
}
    
Real UserTransMaterial:: S2d(Real x, Real y, Real time)
{
    Real s;

    s =  ( -2.0*(x*(x-1.0)+y*(y-1.0)) ) * exp(-time);
    return s;
}

Real UserTransMaterial:: S3d(Real x, Real y, Real z, Real time)
{
    Real s;

    s = ( -x*(x-1.0)*y*(y-1.0)*z*(z-1.0) 
	  - 2.0*( x*(x-1.0)*z*(z-1.0) 
 	        + y*(y-1.0)*z*(z-1.0) 
	        + x*(x-1.0)*y*(y-1.0)  
		)
	) *exp(-time);
    return s;
}
//-------------------------------------------------------------------------


Real UserTransMaterial:: Neumann(int /*type*/, Vector<Real>* x, Real time)
{
    Vector<Real>& xx = *x;

    switch(spaceDim)
    {
      case 1: return time*exp(time);  
      case 2: return -xx[1]*(xx[1]-1.0) * (2.0*xx[2]-1.0)* exp(-time);
      case 3: return xx[1]*(xx[1]-1.0) * xx[2]*(xx[2]-1.0) * 
			(2.0*xx[3]-1.0)* exp(-time);
      default: cout.flush(); abort(); return 0;
    }
}

//-------------------------------------------------------------------------
Real UserTransMaterial:: Cauchy(int /*type*/, Vector<Real>* x, Real time)
{
    Vector<Real>& xx = *x;

    switch(spaceDim)
    {
      case 1: return time*exp(time);  
      case 2: return -xx[1]*(xx[1]-1.0) * (2.0*xx[2]-1.0)* exp(-time);
      case 3: return xx[1]*(xx[1]-1.0) * xx[2]*(xx[2]-1.0) * 
			(2.0*xx[3]-1.0)* exp(-time);
      default: cout.flush(); abort(); return 0;
    }
}

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

Bool  UserTransMaterial:: trueSolKnown()
{
  return True;
}; 

Num UserTransMaterial:: trueSolInPoint(const Vector<Real>& x, const Real time)
{
  switch(spaceDim)
    {
      case 1:          // user-static-1d.cmd
              {
		return  exp(time * x[1]);                             
	      }
      case 2:         // user-static-2d.cmd
	      { 
		return x[1]*(x[1]-1.0) * x[2]*(x[2]-1.0)* exp(-time);
	      }
      case 3:         // user-static-3d.cmd
	      {
		return x[1]*(x[1]-1.0) * x[2]*(x[2]-1.0) * x[3]*(x[3]-1.0) * exp(-time);
	      }
      default: cout.flush(); abort(); return 0;
    }
}

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

void UserTransDirichlet:: setBC(int node, int id, Vector<Real>& x, int /*comp*/, 
			   Real time)
{

   Id[node] = id;

   Values[node] = value(x,time);
}
//-------------------------------------------------------------------------
 

Real UserTransDirichlet:: value(Vector<Real>& x) const
{
    int spaceDim = x.h;

    switch(spaceDim)
    {
      case 1: return 1.0; 
      case 2: return x[1]*(x[1]-1.0) * x[2]*(x[2]-1.0); 
      case 3: return x[1]*(x[1]-1.0) * x[2]*(x[2]-1.0) * x[3]*(x[3]-1.0); 
      default: cout.flush(); abort(); return 0;
    } 
}

//-------------------------------------------------------------------------
 
Real UserTransDirichlet:: value(Vector<Real>& x, Real time) const
{
    int spaceDim = x.h;

    switch(spaceDim)
    {
      case 1: return userBC1d(x[1],time); 
      case 2: return userBC2d(x[1], x[2], time); 
      case 3: return userBC3d(x[1], x[2], x[3], time); 
      default: cout.flush(); abort(); return 0;
    }
}

//-------------------------------------------------------------------------
Real UserTransDirichlet:: userBC1d(Real x, Real time) const
{
    return exp(time * x);
}

Real UserTransDirichlet:: userBC2d(Real x, Real y, Real time) const
{
    Real sum;
    
    sum = x*(x-1.0) * y*(y-1.0)* exp(-time);
    return sum;
}


Real UserTransDirichlet:: userBC3d(Real x, Real y, Real z, Real time) const
{
    Real sum;
    
    sum = x*(x-1.0) * y*(y-1.0) * z*(z-1.0) * exp(-time);
    return sum;
}

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

Real UserTransDirichlet:: initialValue(Vector<Real>& x, Real /*time*/, int /*comp*/) const
{
    return value(x);
}
//-------------------------------------------------------------------------

