-
Notifications
You must be signed in to change notification settings - Fork 7
Create a linear version of the types #5
Comments
Linear Transient FE OperatorsI am thinking about the definition of linear transient FE operators in For linear problems, there is not much to do. I think that the To construct operators using the a-l form (bilinear and linear forms), I would create a constructor of the current Constant Transient FE OperatorsHere the problem is that we are creating a new operator each time step, and now we want to preserve it. Probably, the idea is to keep the operator in the Additionally, we can consider a constant version of the operator that can be constructed from I would try hardly not to create new constant versions of |
I would try to make the transient code as analogous as possible to the steady state. Disclaimer: the names below can be improved. For instance, the terms in the heat equations with Neumann bcs: m(t,ut,v) = ut*v
a(t,u,v) = ∇(v)⊙∇(u)
l_Ω(t,v) = v*f(t)
l_Γ(t,v) = v*g(t)
t_Ω = TransientAffineFETerm(m,a,l_Ω,trian,quad)
t_Γ = TransientFESource(l_Γ,trian_Γ,quad_Γ)
hasconstcoeffs=true
op = TransientAffineFEOperator{hasconstcoeffs}(U,V,t_Ω,t_Γ)
This is true, but I think it would compute more things than strictly needed, you cannot take advantage of elemental matrices to impose Dirichlet boundary conditions, etc. To avoid this, I would introduce the same ingredients as in the steady state case: # C flags if it is constant or not
abstract type AffineODEOperator{C} <: ODEOperator end
funciton matrix!(K,op::AffineODEOperator,t::Real)
@abstractmethod
end
funciton matrix_t!(M,op::AffineODEOperator,t::Real)
@abstractmethod
end
funciton vector!(b,op::AffineODEOperator,t::Real)
@abstractmethod
end
abstract type AffineTransientFEOperator{C} <:TransientFEOperator end
funciton matrix!(K,feop::AffineTransientFEOperator,t::Real)
@abstractmethod
end
funciton matrix_t!(M,feop::AffineTransientFEOperator,t::Real)
@abstractmethod
end
funciton vector!(b,feop::AffineTransientFEOperator,t::Real)
@abstractmethod
end
function get_algebraic_operator(feop::AffineTransientFEOperator{C}) where C
AffineODEOpFromFEOp{C}(feop)
end
struct AffineODEOpFromFEOp{C} <: AffineODEOperator{C} end
# The actual implementation is here
struct AffineTransientFEOperatorFromTerms <: AffineTransientFEOperator{false} end
struct ConstantAffineTransientFEOperatorFromTerms <: AffineTransientFEOperator{true} end
Then the This introduces new types, but It opens the door to implement all the optimizations one would expect for linear problems. Perhaps it is a good idea to discuss it face-to-face. |
Before discussing the FE part, and whether or not we want to start creating transient FE terms for all possible combinations (now we have three kinds of terms, not two), I think it is better to have a clear idea of how to deal with constant operators in Being said that, I think that the main issue is how to deal with constant operators (and constant right-hand side and time step size due to Dirichlet data, otherwise I am not sure how we can do this, since we do not keep the Free-Dirichlet block of the matrix in Gridap). What do we need to accommodate this situation in the I think we must create a When it will work, we can think about a Anyway, let us have a chat on this to speed up the process. |
I propose:
and
However, it won't work because Probably doing this
|
OK, we can start by considering the affine non-constant scenario as a particular non-linear case. We can define this constructor function Gridap.AffineFETerm(
m::Function,a::Function,b::Function,trian::Triangulation,quad::CellQuadrature)
res(t,u,ut,v) = m(t,ut,v) + a(t,u,v) - b(t,v)
jac(t,u,ut,du,v) = a(t,du,v)
jac_t(t,u,ut,dut,v) = m(t,dut,v)
FETerm(res,jac,jac_t,trian,quad)
end In order to write m(t,ut,v) = ut*v
a(t,u,v) = ∇(v)⋅∇(u)
b(t,v) = v*f(t)
t_Ω = AffineFETerm(m,a,b,trian,quad)
op = TransientFEOperator(U,V0,t_Ω) instead of a(u,v) = ∇(v)⋅∇(u)
b(v,t) = v*f(t)
res(t,u,ut,v) = a(u,v) + ut*v - b(v,t)
jac(t,u,ut,du,v) = a(du,v)
jac_t(t,u,ut,dut,v) = dut*v
t_Ω = FETerm(res,jac,jac_t,trian,quad)
op = TransientFEOperator(U,V0,t_Ω) |
On the other hand, I will create a new abstract type This is the interface for this abstract type: abstract type ConstantODEOperator <: ODEOperator
get_matrix(op::ConstantODEOperator) = @abstractmethod
get_matrix_t(op::ConstantODEOperator) = @abstractmethod
vector!(b,op::ConstantODEOperator,t::Real,ode_cache) = @abstractmethod
# + Other methods in the ODEOperator interface Then, we can implement an efficient version of function solve_step!(uf::AbstractVector,
solver::ThetaMethod,
op::ConstantODEOperator,
u0::AbstractVector,
t0::Real,
cache)
dt = solver.dt
solver.θ == 0.0 ? dtθ = dt : dtθ = dt*solver.θ
tθ = t0+dtθ
if cache === nothing
ode_cache = allocate_cache(op)
vθ = similar(u0)
bθ = similar(u0)
ls_cache = nothing
K = get_matrix(op)
M = get_matrix_t(op)
A = (1/dtθ)*M + K
ls_cache = nothing
else
ode_cache, vθ, bθ, A, ls_cache = cache
end
ode_cache = update_cache!(ode_cache,op,tθ)
vector!(bθ,op,tθ,ode_cache)
aop = AffineOperator(A,bθ)
newmatrix = false
ls_cache = solve!(uf,solver.nls,aop,ls_cache,newmatrix)
if 0.0 < solver.θ < 1.0
uf = uf*(1.0/solver.θ)-u0*((1-solver.θ)/solver.θ)
end
cache = (ode_cache, vθ, bθ, A, ls_cache)
tf = t0+dt
return (uf,tf,cache)
end |
The last ingredient is a specialization of Here, we could even precompute the dirichlet blocks of M and K using the DirichletFESpace so that we only integrate the source terms at each time step |
Hi @fverdugo I have done an implementation of affine and constant operators. I have finally decided to use traits, I find it is a nice way to provide the required functionality with a minimum number of lines. I have to test the code, we can talk at some point, but I wanted to ask you about this error
I always have issues with the constructor for |
Try to remove the
|
Even though there is still room for optimisation, I think that the implementation after PR #18 solve this issue |
Up to now, I am considering general nonlinear solvers and operators.
We should consider also linear ones for performance.
For efficiency, we should explore the case in which the
TrialFESpace
is constant, not being tested yet.The text was updated successfully, but these errors were encountered: