Handle generalized behaviours with block structure
Many pairs of Gradient/Flux are defined in MFront, each flux \sigma_i
being associated with one gradient g_i
so that internal power is assumed to be
\sigma_i\cdot\delta{g}_i dx
. Each flux may depend on all gradients and state variables (temperature in particular), this will be handled using tangent_operator_blocks
. The only thing which needs to be done is to register the gradient operator with something like:
problem.register_gradient("TotalStrain", sym(grad(u)))
problem.register_gradient("TemperatureGradient", grad(T))
problem.register_gradient("TransformationGradient", Identity(dim)+grad(u))
for such classical gradient operators, we can implement them by default. Note that expressions depend on the hypothesis. For more general behaviours like multiphase models for instance, we can have:
u = Function(V)
(u1, u2) = split(u)
problem.register_gradient("Strain1", sym(grad(u1)))
problem.register_gradient("Strain2", sym(grad(u2)))
problem.register_gradient("RelativeDisplacement", u2-u1)
For more general behaviours which do not fit into this scope, we could ask for registering (or just writing?) explicitly the terms of the variational form:
H = problem.get_state_variable("Enthalpy")
H0 = H.previous()
j = problem.get_thermodynamical_force("HeatFlux")
j0 = j.previous()
problem.register_term(H-H0, test_field="Temperature")
problem.register_term(dt*(theta*j-(1-theta)*j0), test_field="TemperatureGradient")
# or instead of the last two lines just do
problem.L = (T_*(H-H0)+dt*(theta*dot(grad(T_), j)-(1-theta)*dot(grad(T_) ,j0)))*dx