How to specify a variable coefficient tensor

Asked by Jack

Hi

I'd like to specify a variable coefficient tensor, but not in the ufl form file. A snippet of the ufl form file is:

==
D = TensorConstant("triangle")

....

a = u*v*dx + dt*theta*inner( D*grad(u), grad(v) )*dx
L = u_old*v*dx - dt*(1-theta) * inner( D*grad(u_old), grad(v) )*dx + dt*theta*f*v*dx
==

D is a 2x2 tensor which I construct from main.cpp in a subclass of expression. So, I have:

class VariableCoefficientTensor : public Expression {
public:
    ....
    void eval(Array<double>& values, const Array<double>& x) const {
        ...
        values[0] = some_value;
        values[1] = some_value_too
};

int main()
{
        ...
     VariableCoefficientTensor D;
 a.D = D;
        ...
}
==

When I execute the program, I get:

terminate called after throwing an instance of 'std::runtime_error'
  what(): *** Error: Invalid value rank for coefficient 0, got 0 but expecting 2. Did you forget to specify the value rank correctly in an Expression sub class?

What's the correct way to go about this?

Thanks

Jack

Question information

Language:
English Edit question
Status:
Solved
For:
DOLFIN Edit question
Assignee:
No assignee Edit question
Solved by:
Garth Wells
Solved:
Last query:
Last reply:
Revision history for this message
Best Garth Wells (garth-wells) said :
#1

On Wed, 2010-08-18 at 19:29 +0000, Jack wrote:
> New question #121743 on DOLFIN:
> https://answers.launchpad.net/dolfin/+question/121743
>
> Hi
>
> I'd like to specify a variable coefficient tensor, but not in the ufl form file. A snippet of the ufl form file is:
>
> ==
> D = TensorConstant("triangle")
>
> ....
>
> a = u*v*dx + dt*theta*inner( D*grad(u), grad(v) )*dx
> L = u_old*v*dx - dt*(1-theta) * inner( D*grad(u_old), grad(v) )*dx + dt*theta*f*v*dx
> ==
>
> D is a 2x2 tensor which I construct from main.cpp in a subclass of expression. So, I have:
>
>
> class VariableCoefficientTensor : public Expression {
> public:
> ....
> void eval(Array<double>& values, const Array<double>& x) const {
> ...
> values[0] = some_value;
> values[1] = some_value_too
> };
>
> int main()
> {
> ...
> VariableCoefficientTensor D;
> a.D = D;
> ...
> }
> ==
>
> When I execute the program, I get:
>
> terminate called after throwing an instance of 'std::runtime_error'
> what(): *** Error: Invalid value rank for coefficient 0, got 0 but expecting 2. Did you forget to specify the value rank correctly in an Expression sub class?
>
>
> What's the correct way to go about this?
>

Try

  class VariableCoefficientTensor : public Expression
  {
     public:
       VariableCoefficientTensor() : Expression(2, 2) ();

       void eval(Array<double>& values, const Array<double>& x) const
       { . . . . }

  }

Have a look in dolfin/function/Expression.h for details.

Garth

> Thanks
>
> Jack
>
>

Revision history for this message
Jack (attacking-chess) said :
#2

Thanks Garth Wells, that solved my question.

Revision history for this message
Jack (attacking-chess) said :
#3

That worked, thank you.

Could I just confirm that with Expression(2,2), the values array will have 4 components like below:

values[0] = entry (0,0)
values[1] = entry (0,1)
values[2] = entry (1,0)
values[3] = entry (1,1)

Jack

Revision history for this message
Anders Logg (logg) said :
#4

On Thu, Aug 19, 2010 at 12:14:06AM -0000, Jack wrote:
> Question #121743 on DOLFIN changed:
> https://answers.launchpad.net/dolfin/+question/121743
>
> Jack posted a new comment:
> That worked, thank you.
>
> Could I just confirm that with Expression(2,2), the values array will
> have 4 components like below:
>
> values[0] = entry (0,0)
> values[1] = entry (0,1)
> values[2] = entry (1,0)
> values[3] = entry (1,1)

Yes.

--
Anders

Revision history for this message
Jack (attacking-chess) said :
#5

Thanks.