Function to fill fespace

Hello all,

I would like to know what are the available methods to assign values to a fespace variable.

I am trying to solve a transient diffusion problem where the diffusivity depends upon the variable of interest. For this purpose I have code which looks as follows:

func real diff(real X, real T) {
	real Deff;
	Deff = 2.4e-7 * ( 1 - exp(-7.9e14*(X^15.7)) + X^0.686 ) * exp(-3156/(T+273));
	return Deff;
}

real u0 = 0.3, T = 40;
fespace Vh(Th,P1);
Vh u = u0, v, uold, diffu;

// ...

problem diffusion(u,v) = 
	int2d(Th) (u*v/dt + diffu*(dx(u)*dx(v) + dy(u)*dy(v)))
  - int2d(Th) (uold*v/dt)
  + on(2,u=0.1);

// ...

for (int i = 0; i < nsteps; i++) {
	uold = u;

    // Evaluate diffusivity
    for (int i = 0; i < Vh.ndof; i++) {
        diffu[][i] = diff(uold[][i],T);
    }

	diffusion;
	t += dt;
}

Is the preferred solution to use a macro like

macro diff(X,T) 
   2.4e-7 * ( 1 - exp(-7.9e14*(X^15.7)) + X^0.686 ) * exp(-3156/(T+273)) // EOM

in place of my current loop calling the scalar function?

Using a macro instead of a func is a better, you are correct.
Also, this loop will be slow:

    for (int i = 0; i < Vh.ndof; i++) {
        diffu[][i] = diff(uold[][i],T);
    }

Best to use:

    for [i, v : diffu[]] {
        v = diff(uold[][i],T);
    }

You can lookup “Implicit loop” in the documentation.

Thanks for the tip about implicit loops. I haven’t seen these used very often in examples.

They appear to be kind of a hybrid between Python:

for i, ai in enumerate(a):
    ...

and the access iterator in C++:

for (auto &ai: a) {
    ...
}