diff --git a/src/JuliaFEM.jl b/src/JuliaFEM.jl index d747ea4..78268ba 100644 --- a/src/JuliaFEM.jl +++ b/src/JuliaFEM.jl @@ -10,6 +10,10 @@ module JuliaFEM #@Logging.configure(level=DEBUG) #using Lexicon +import Base: +, -, /, *, push!, convert, getindex, length, similar, call, vec, endof + +#importall Base + """ A very simple debugging macro. It prints debug message if environment variable JULIAFEM_DEBUG is found. @@ -78,6 +82,7 @@ include("elasticity.jl") ### ASSEMBLY + SOLVE ### include("assembly.jl") include("solvers.jl") +include("directsolver.jl") # parallel sparse direct solver for non-lniear problems # PRE AND POSTPROCESS include("xdmf.jl") diff --git a/src/directsolver.jl b/src/directsolver.jl new file mode 100644 index 0000000..8fea44b --- /dev/null +++ b/src/directsolver.jl @@ -0,0 +1,114 @@ +# This file is a part of JuliaFEM. +# License is MIT: see https://github.com/JuliaFEM/JuliaFEM.jl/blob/master/LICENSE.md + +## Direct solver + +type DirectSolver <: Solver + field_problems :: Vector{FieldProblem} + boundary_problems :: Vector{BoundaryProblem} + nonlinear_problem :: Bool + max_iterations :: Int64 + tol :: Float64 +end + +function push!(solver::DirectSolver, problem::FieldProblem) + push!(solver.field_problems, problem) +end + +function push!(solver::DirectSolver, problem::BoundaryProblem) + push!(solver.boundary_problems, problem) +end + +""" Default initializer. """ +function DirectSolver() + DirectSolver([], [], true, 10, 1.0e-6) +end + +""" Call solver to solve a set of problems. """ +function call(solver::DirectSolver, time::Number=0.0) + @assert length(solver.field_problems) == 1 + @assert length(solver.boundary_problems) == 1 + @assert solver.nonlinear_problem == true + + problem1 = solver.field_problems[1] + problem2 = solver.boundary_problems[1] + + x = zeros(3) + dx = zeros(3) + dims = nothing + + for iter=1:solver.max_iterations + tic() + info("Starting iteration $iter") + assembly1 = Assembly() + assemble!(assembly1, problem1, time) + assembly2 = Assembly() + assemble!(assembly2, problem2, time) + + A1 = sparse(assembly1.stiffness_matrix) + dims = size(A1) + b1 = sparse(assembly1.force_vector, dims[1], 1) + A2 = sparse(assembly2.stiffness_matrix, dims[1], dims[2]) + b2 = sparse(assembly2.force_vector, dims[1], 1) + + # create a saddle point problem + A = [A1 A2; A2' zeros(A2)] + b = [b1; b2] + + if length(b) != length(x) + info("iter $iter: resizing solution vector") + resize!(x, length(b)) + resize!(dx, length(b)) + fill!(x, 0.0) + fill!(dx, 0.0) + end + + # solve problem, update solution vector + nz = unique(rowvals(A)) # take only non-zero rows + dx[nz] = lufact(A[nz,nz]) \ full(b[nz]) + x += dx + + # get "problem-wise" solution vectors + x1 = x[1:dims[1]] + x2 = x[dims[1]+1:end] + + # update field for elements in problem 1 + for equation in get_equations(problem1) + element = get_element(equation) + field_name = get_unknown_field_name(problem1) + gdofs = get_gdofs(problem1, equation) + local_sol = vec(full(x1[gdofs])) + eqsize = size(equation) + if eqsize[1] != 1 + local_sol = reshape(local_sol, eqsize) + end + #info("problem1: pushing to $field_name") + push!(element[field_name], time => local_sol) + end + + # update field for elements in problem 2 (Dirichlet boundary) + for equation in get_equations(problem2) + element = get_element(equation) + field_name = "reaction force" #get_unknown_field_name(problem2) + gdofs = get_gdofs(problem2, equation) + local_sol = vec(full(x1[gdofs])) + eqsize = size(equation) + if eqsize[1] != 1 + local_sol = reshape(local_sol, eqsize) + end + #info("problem2: pushing to $field_name") + push!(element[field_name], time => local_sol) + end + + if norm(dx[1:dims[1]]) < solver.tol + return (iter, true) + end + + info("Iteration took $(toq()) seconds") + end + + info("Warning: did not coverge in $(solver.max_iterations) iterations!") + return (solver.max_iterations, false) + +end + diff --git a/src/dirichlet.jl b/src/dirichlet.jl index 4a220b7..cb18a78 100644 --- a/src/dirichlet.jl +++ b/src/dirichlet.jl @@ -3,11 +3,7 @@ # Dirichlet boundary conditions in weak form -abstract DirichletEquation <: Equation - -function get_unknown_field_name(equation::DirichletEquation) - return "reaction force" -end +abstract DirichletEquation <: BoundaryEquation ### Dirichlet problem + equations @@ -15,8 +11,6 @@ type DirichletProblem <: BoundaryProblem unknown_field_name :: ASCIIString unknown_field_dimension :: Int equations :: Vector{DirichletEquation} -# element_mapping :: Dict{DataType, DataType} - field_value :: Function end """ Initialize new Dirichlet boundary condition. @@ -24,27 +18,14 @@ end Parameters ---------- dimension - dimension of unknown field -field_value - boundary function + dimension of unknown field (scalar, vector, ...) Examples -------- -Create u(X) = 0.0 boundary condition for three-dimensional elasticity problem: - ->>> u(X) = [0.0, 0.0, 0.0] ->>> bc = DirichletProblem(3, u) """ -function DirichletProblem(dimension::Int=1, field_value::Function=(X)->[0.0,0.0,0.0], equations=[]) -# element_mapping = nothing -# if dimension == 1 -# element_mapping = Dict( -# Seg2 => DBC2D2 -# ) -# end - DirichletProblem("reaction force", dimension, equations, field_value) -# DirichletProblem("reaction force", dimension, [], element_mapping, field_value) +function DirichletProblem(unknown_field_name::ASCIIString, dimension::Int=1) + DirichletProblem(unknown_field_name, dimension, []) end """ Dirichlet boundary condition element for 2 node line segment """ @@ -57,31 +38,45 @@ function Base.size(equation::DBC2D2) return (1, 2) end -#function DBC2D2(element::Seg2) function Base.convert(::Type{DirichletEquation}, element::Seg2) integration_points = line3() - haskey(element, "reaction force") || (element["reaction force"] = zeros(1, 2)) + haskey(element, "reaction force") || (element["reaction force"] = 0.0 => zeros(2)) DBC2D2(element, integration_points) end function assemble!(assembly::Assembly, equation::DirichletEquation, time::Number=0.0, problem=nothing) - gdofs = get_gdofs(equation) -# info("gdofs = $gdofs") + isa(problem, Void) && error("Dicihlet boundary condition needs problem defined") + field_dim = problem.unknown_field_dimension + field_name = problem.unknown_field_name element = get_element(equation) + gdofs = get_gdofs(element, field_dim) basis = get_basis(element) detJ = det(basis) for ip in get_integration_points(equation) w = ip.weight * detJ(ip) N = basis(ip, time) - add!(assembly.stiffness_matrix, gdofs, gdofs, w*N'*N) -# info("added $(w*N'*N)") -# if !isa(problem, Void) -# X = basis("geometry", ip, time) -# u = problem.field_value(X)[1:length(gdofs)] -# add!(assembly.force_vector, gdofs, w*N'*u) -# end + A = w*N'*N + + if haskey(element, field_name) + # add all dimensions at once + for i=1:field_dim + g = element(field_name, ip, time) + ldofs = gdofs[i:field_dim:end] + add!(assembly.stiffness_matrix, ldofs, ldofs, A) + add!(assembly.force_vector, ldofs, w*g*N') + end + end + + for i=1:field_dim + if haskey(element, field_name*" $i") + # add single component + g = element(field_name*" $i", ip, time) + ldofs = gdofs[i:field_dim:end] + add!(assembly.stiffness_matrix, ldofs, ldofs, A) + add!(assembly.force_vector, ldofs, w*g*N') + end + end end -# info("assembly done") end diff --git a/src/elasticity.jl b/src/elasticity.jl index 0885c94..8452dc8 100644 --- a/src/elasticity.jl +++ b/src/elasticity.jl @@ -3,7 +3,7 @@ # Elasticity problems -abstract ElasticityProblem <: Problem +abstract ElasticityProblem <: FieldProblem abstract ElasticityEquation <: Equation function get_unknown_field_name(equation::ElasticityEquation) diff --git a/src/elements.jl b/src/elements.jl index 527424e..63ffaaa 100644 --- a/src/elements.jl +++ b/src/elements.jl @@ -67,6 +67,10 @@ function Base.getindex(element::Element, field_name) return element.fields[field_name] end +function get_integration_points(element) + return get_default_integration_points(element) +end + """Add new Field to element. Examples @@ -78,6 +82,9 @@ Examples function Base.setindex!(element::Element, data, name::ASCIIString) element.fields[name] = Field(data) end +function Base.setindex!(element::Element, field::Field, name::ASCIIString) + element.fields[name] = field +end function Base.setindex!(element::Element, data::Tuple, name::ASCIIString) element.fields[name] = Field(data...) end @@ -143,6 +150,39 @@ function call(gradu::GradientFunctionSpace, field_name, xi::Union{Vector, Integr gradu.basis(geometry, field, xi, Val{:grad}) end +typealias VecOrIP Union{Vector, IntegrationPoint} + +function Base.call(element::Element, field_name::ASCIIString, xi::VecOrIP, time::Number) + return element.basis(element[field_name](time), xi) +end + +function Base.call(element::Element, field_name::ASCIIString, xi::VecOrIP, time::Number, ::Type{Val{:grad}}) + return element.basis(element["geometry"](time), element[field_name](time), xi, Val{:grad}) +end + +function Base.call(element::Element, field_name::ASCIIString, xi::VecOrIP) + return element.basis(element[field_name], xi) +end + +function Base.call(element::Element, field_name::ASCIIString, xi::VecOrIP, ::Type{Val{:grad}}) + return element.basis(element["geometry"], element[field_name], xi, Val{:grad}) +end + +function Base.call(element::Element, field_name::ASCIIString, time::Number) + return element[field_name](time) +end + +function Base.call(element::Element, xi::VecOrIP) + element.basis(xi) +end + +function Base.call(element::Element, xi::VecOrIP, ::Type{Val{:grad}}) + element.basis(element["geometry"], xi, Val{:grad}) +end + +function Base.call(element::Element, field_name::ASCIIString) + return element[field_name] +end # on-line functions to get api more easy to use, ip -> xi.ip #call(u::FunctionSpace, ip::IntegrationPoint, t::Number=Inf) = call(u, ip.xi, t) @@ -176,12 +216,19 @@ function LinAlg.det(u::FunctionSpace, xi::Vector, time::Number=0.0) m, n = size(J) return m == n ? det(J) : norm(J) end + function LinAlg.det(u::FunctionSpace, ip::IntegrationPoint, time::Number=0.0) LinAlg.det(u, ip.xi, time) end + function LinAlg.det(u::FunctionSpace) return (args...) -> det(u, args...) end + +function LinAlg.det(element::Element) + return det(get_basis(element)) +end + #Base.(:+)(u::FunctionSpace, v::FunctionSpace) = (args...) -> u(args...) + v(args...) #Base.(:-)(u::FunctionSpace, v::FunctionSpace) = (args...) -> u(args...) - v(args...) #Base.(:+)(u::GradientFunctionSpace, v::GradientFunctionSpace) = (args...) -> u(args...) + v(args...) diff --git a/src/equations.jl b/src/equations.jl index bd8e206..8c610a5 100644 --- a/src/equations.jl +++ b/src/equations.jl @@ -4,6 +4,8 @@ # Functions to handle element level things -- integration, assembly, ... abstract Equation +abstract FieldEquation <: Equation +abstract BoundaryEquation <: Equation type Assembly mass_matrix :: SparseMatrixIJV diff --git a/src/fields2.jl b/src/fields2.jl index d36713a..98c95eb 100644 --- a/src/fields2.jl +++ b/src/fields2.jl @@ -12,6 +12,7 @@ abstract Variable <: AbstractField abstract TimeVariant <: AbstractField abstract TimeInvariant <: AbstractField + type Field{A<:Union{Discrete,Continuous}, B<:Union{Constant,Variable}, C<:Union{TimeVariant,TimeInvariant}} data end @@ -81,6 +82,10 @@ typealias TimeVariantField Union{DCTV, DVTV, CCTV, CVTV} ### Convenient functions to create fields +#function Base.convert(::Type{Field}, data) +# return Field(data) +#end + function Field(data) return DCTI(data) end @@ -101,6 +106,20 @@ function Base.convert{T}(::Type{DCTV}, data::Pair{Float64, Vector{T}}...) return DCTV([Increment{Vector{T}}(d[1], d[2]) for d in data]) end +function Field(func::Function) + if method_exists(func, Tuple{}) + return CCTI(func) + elseif method_exists(func, Tuple{Float64}) + return CCTV(func) + elseif method_exists(func, Tuple{Vector}) + return CVTI(func) + elseif method_exists(func, Tuple{Vector, Number}) + return CVTV(func) + else + error("no proper definition found for function: check methods.") + end +end + function CVTI(basis::Function, dbasis::Function) return CVTI(Basis(basis, dbasis)) end @@ -203,28 +222,55 @@ function Base.convert(::Type{Basis}, field::CVTI) return field.data end +function Base.call(field::CCTV, time::Number) + return field.data(time) +end + ### Interpolation +""" Interpolate time-invariant field in time direction. """ function Base.call(field::DVTI, time::Float64) - # interpolating time-invariant field in time direction -> no effect return field end - function Base.call(field::DCTI, time::Float64) - # interpolating time-invariant field in time direction -> no effect return field end +function Base.call(field::CVTI, time::Float64) + return field.data() +end +function Base.call(field::CCTI, time::Float64) + return field.data() +end +""" Interpolate time-variant field in time direction. """ +function Base.call(field::DCTV, time::Float64) + for i=reverse(1:length(field)) + if isapprox(field[i].time, time) + return DCTI(field[i].data) + end + end + info(field.data) + info(time) + error("interpolate DCTV: not implemented yet") +end + +function Base.call(field::DVTV, time::Float64, time_extrapolation::Symbol=:linear) + for i=reverse(1:length(field)) + if isapprox(field[i].time, time) + return DVTI(field[i].data) + end + end + info(field.data) + info(time) + error("interpolate DVTV: not implemented yet") +end + +""" Interpolate constant field in spatial dimension. """ function Base.call(basis::CVTI, field::DCTI, xi::Vector) - # try to interpolate constant value -> no effect - return field + return field.data end -#function Base.call(basis::Basis, field::DCTI, xi::Vector) - # calling constant field with basis -> no effect -# return field -#end - +""" Interpolate variable field in spatial dimension. """ function Base.call(basis::CVTI, values::DVTI, xi::Vector) N = basis(xi) return sum([N[i]*values[i] for i=1:length(N)]) @@ -244,27 +290,8 @@ function Base.call(basis::CVTI, geometry::DVTI, values::DVTI, xi::Vector, ::Type return length(gradf) == 1 ? gradf[1] : gradf end -function Base.call(field::DCTV, time::Float64) - for i in length(field) - if isapprox(field[i].time, time) - return DCTI(field[i].data) - end - end - error("interpolate DCTV: not implemented yet") -end - -function Base.call(field::DVTV, time::Float64, time_extrapolation::Symbol=:linear) -# info("length of field DVTV: $(length(field))") - for i=reverse(1:length(field)) - res = isapprox(field[i].time, time) - #info("isapprox $(field[i].time) to $time ? $res") - if isapprox(field[i].time, time) - return DVTI(field[i].data) - end - end - info(field.data) - info(time) - error("interpolate DVTV: not implemented yet") +function Base.call(basis::CVTI, xi::Vector, time::Number) + call(basis, xi) end ### FIELDSET ### diff --git a/src/solvers.jl b/src/solvers.jl index 0ae9831..3f1cbd7 100644 --- a/src/solvers.jl +++ b/src/solvers.jl @@ -9,7 +9,7 @@ abstract Solver Solve field equations for single element with some dofs fixed. This can be used to test nonlinear element formulations. """ -function solve!(equation::Equation, free_dofs::Vector{Int}, time::Number; max_iterations::Int=10, tolerance::Float64=1.0e-12, dump_matrices::Bool=false) +function solve!(equation::Equation, free_dofs::Vector{Int}, time::Number; max_iterations::Int=10, tolerance::Float64=1.0e-12, dump_matrices::Bool=false, callback=nothing) unknown_field_name = get_unknown_field_name(equation) element = get_element(equation) x0 = element[unknown_field_name](0.0) @@ -31,6 +31,9 @@ function solve!(equation::Equation, free_dofs::Vector{Int}, time::Number; max_it data = eqsize[1] != 1 ? reshape(x, eqsize) : x push!(element[unknown_field_name], time => data) norm(dx) < tolerance && return + if !isa(callback, Void) + callback(x) + end end error("Did not converge in $max_iterations iterations") end @@ -41,7 +44,7 @@ to test nonlinear element formulations. Dirichlet boundary is assumed to be homo and degrees of freedom are eliminated. So if boundary condition is known in nodal points and everything is zero this should be quite good. """ -function solve!(problem::Problem, free_dofs::Vector{Int}, time::Float64; max_iterations::Int=10, tolerance::Float64=1.0e-12, dump_matrices::Bool=false) +function solve!(problem::Problem, free_dofs::Vector{Int}, time::Float64; max_iterations::Int=10, tolerance::Float64=1.0e-12, dump_matrices::Bool=false, callback=nothing) info("start solver") assembly = Assembly() # x = zeros(ga.ndofs) @@ -66,6 +69,9 @@ function solve!(problem::Problem, free_dofs::Vector{Int}, time::Float64; max_ite dx[free_dofs] = lufact(A[free_dofs,free_dofs]) \ full(b)[free_dofs] info("Difference in solution norm: $(norm(dx))") x += dx + if !(isa(callback, Void)) + callback(x) + end for equation in get_equations(problem) element = get_element(equation) gdofs = get_gdofs(equation) @@ -81,11 +87,6 @@ function solve!(problem::Problem, free_dofs::Vector{Int}, time::Float64; max_ite error("Did not converge in $max_iterations iterations") end -""" Add new problem to solver. """ -function add_problem!(solver::Solver, problem::Problem) - push!(solver.problems, problem) -end - function Base.push!(solver::Solver, problem::Problem) push!(solver.problems, problem) end @@ -126,9 +127,10 @@ function call(solver::SimpleSolver, time::Number=0.0) # info("Creating sparse matrices") A1 = sparse(assembly1.stiffness_matrix) - b1 = sparse(assembly1.force_vector, size(A1, 1), 1) - A2 = sparse(assembly2.stiffness_matrix) - b2 = sparse(assembly2.force_vector, size(A2, 1), 1) + dims = size(A1) + b1 = sparse(assembly1.force_vector, dims[1], 1) + A2 = sparse(assembly2.stiffness_matrix, dims[1], dims[2]) + b2 = sparse(assembly2.force_vector, dims[1], 1) # create a saddle point problem A = [A1 A2; A2' zeros(A2)] @@ -149,16 +151,28 @@ function call(solver::SimpleSolver, time::Number=0.0) field_name = get_unknown_field_name(problem1) gdofs = get_gdofs(problem1, equation) local_sol = vec(full(x1[gdofs])) + eqsize = size(equation) + if eqsize[1] != 1 + local_sol = reshape(local_sol, eqsize) + end + #info("problem1: pushing to $field_name") push!(element[field_name], time => local_sol) end # update field for elements in problem 2 (Dirichlet boundary) for equation in get_equations(problem2) element = get_element(equation) - field_name = get_unknown_field_name(problem2) + field_name = "reaction force" #get_unknown_field_name(problem2) gdofs = get_gdofs(problem2, equation) local_sol = vec(full(x1[gdofs])) + eqsize = size(equation) + if eqsize[1] != 1 + local_sol = reshape(local_sol, eqsize) + end + #info("problem2: pushing to $field_name") push!(element[field_name], time => local_sol) end + + return norm(x1) end diff --git a/test/test_dirichlet.jl b/test/test_dirichlet.jl index 146f20d..ab448ea 100644 --- a/test/test_dirichlet.jl +++ b/test/test_dirichlet.jl @@ -1,18 +1,60 @@ - # This file is a part of JuliaFEM. # License is MIT: see https://github.com/JuliaFEM/JuliaFEM.jl/blob/master/LICENSE.md -module TestAutoDiffWeakForm +module TestDirichletBoundaryCondition using JuliaFEM.Test using JuliaFEM -using JuliaFEM: Seg2, DirichletProblem +using JuliaFEM: Seg2, DirichletProblem, Assembly, assemble! -function test_dirichlet_problem() - element = Seg2([3, 4]) +function test_dirichlet_problem_1_dim() + element = Seg2([1, 2]) element["geometry"] = Vector[[1.0, 1.0], [0.0, 1.0]] - problem = DirichletProblem(1) + element["temperature"] = 0.0 + problem = DirichletProblem("temperature", 1) push!(problem, element) + assembly = Assembly() + assemble!(assembly, problem) + A = full(assembly.stiffness_matrix) + b = full(assembly.force_vector) + @test isapprox(A, 1/6*[2 1; 1 2]) + @test isapprox(b, [0.0, 0.0]) +end + +function test_dirichlet_problem_2_dim() + element = Seg2([1, 2]) + element["geometry"] = Vector[[1.0, 1.0], [0.0, 1.0]] + element["displacement"] = 0.0 + problem = DirichletProblem("displacement", 2) + push!(problem, element) + assembly = Assembly() + assemble!(assembly, problem) + A = full(assembly.stiffness_matrix) + b = full(assembly.force_vector) + A_expected = 1/6*[2 0 1 0; 0 2 0 1; 1 0 2 0; 0 1 0 2] + @test isapprox(A, A_expected) + @test isapprox(b, [0.0, 0.0, 0.0, 0.0]) +end + +function test_dirichlet_problem_2_dim_single_dof_fixed() + element = Seg2([1, 2]) + element["geometry"] = Vector[[1.0, 1.0], [0.0, 1.0]] + element["displacement 2"] = 0.0 + problem = DirichletProblem("displacement", 2) + push!(problem, element) + assembly = Assembly() + assemble!(assembly, problem) + A = full(assembly.stiffness_matrix) + b = full(assembly.force_vector) + info(b) + info("A = \n$A") + A_expected = 1/6*[ + 0 0 0 0 + 0 2 0 1 + 0 0 0 0 + 0 1 0 2] + @test isapprox(A, A_expected) + @test isapprox(b, [0.0, 0.0, 0.0, 0.0]) end end diff --git a/test/test_elasticity.jl b/test/test_elasticity.jl index d91b506..3d6a837 100644 --- a/test/test_elasticity.jl +++ b/test/test_elasticity.jl @@ -25,27 +25,28 @@ function test_elasticity_volume_load() end function test_elasticity_surface_load() - N = Vector[[0.0, 0.0], [10.0, 0.0], [10.0, 1.0], [0.0, 1.0]] + N = Vector[[0.0, 0.0], [1.0, 0.0], [0.0, 1.0], [1.0, 1.0]] - element1 = Quad4([1, 2, 3, 4]) - element1["geometry"] = Vector[N[1], N[2], N[3], N[4]] - element1["youngs modulus"] = 500.0 - element1["poissons ratio"] = 0.3 + element1 = Quad4([1, 2, 4, 3]) + element1["geometry"] = Vector[N[1], N[2], N[4], N[3]] + element1["youngs modulus"] = 900.0 + element1["poissons ratio"] = 0.25 element2 = Seg2([3, 4]) element2["geometry"] = Vector[N[3], N[4]] - element2["displacement traction force"] = Vector[[0.0, -10.0], [0.0, -10.0]] + element2["displacement traction force"] = Vector[[0.0, -100.0], [0.0, -100.0]] - free_dofs = [3, 4, 5, 6] + #free_dofs = [3, 5, 6, 8] + free_dofs = [3, 6, 7, 8] problem = PlaneStressElasticityProblem() push!(problem, element1) push!(problem, element2) - solve!(problem, free_dofs, 1.0; max_iterations=10) - disp = get_basis(element1)("displacement", [1.0, 1.0], 1.0)[2] + solve!(problem, free_dofs, 0.0; max_iterations=10) + #disp = get_basis(element1)("displacement", [1.0, 1.0], 1.0)[2] + info(last(element1["displacement"])) + disp = element1("displacement", [1.0, 1.0], 0.0) info("displacement at tip: $disp") # verified using Code Aster. - @test isapprox(disp, -9.33106637611714) + @test isapprox(disp, [3.17431158889468E-02, -1.38591518927826E-01]) end -#test_elasticity_volume_load() - end diff --git a/test/test_elements.jl b/test/test_elements.jl index 8e465d1..822a812 100644 --- a/test/test_elements.jl +++ b/test/test_elements.jl @@ -5,7 +5,7 @@ module ElementTests using JuliaFEM.Test -using JuliaFEM: Element, Basis, Field, FieldSet, FunctionSpace, test_element +using JuliaFEM: Element, Field, FieldSet, test_element """ Prototype element @@ -13,11 +13,11 @@ This should always pass test_element if everything is ok. """ type MockElement <: Element connectivity :: Vector{Int} - basis :: Basis + basis :: Field fields :: FieldSet end -function MockElement(connectivity) +function MockElement(connectivity, fields...) h(xi) = 1/4*[ (1-xi[1])*(1-xi[2]) @@ -29,95 +29,51 @@ function MockElement(connectivity) -(1-xi[2]) (1-xi[2]) (1+xi[2]) -(1+xi[2]) -(1-xi[1]) -(1+xi[1]) (1+xi[1]) (1-xi[1])] - basis = Basis(h, dh) - MockElement(connectivity, basis, Dict()) + MockElement(connectivity, Field(h, dh), FieldSet(fields...)) end Base.size(element::Type{MockElement}) = (2, 4) -"""test test_element against mock element""" -function test_mockelement() +""" Return test element with some fields. """ +function get_element() + el = MockElement([1, 2, 3, 4]) + el["geometry"] = Vector{Float64}[[0.0,0.0], [1.0,0.0], [1.0,1.0], [0.0,1.0]] + el["temperature"] = ( + 0.0 => [0.0, 0.0, 0.0, 0.0], + 1.0 => [1.0, 2.0, 3.0, 4.0]) + el["displacement"] = ( + 0.0 => Vector{Float64}[[0.0,0.0], [0.0, 0.0], [0.0,0.0], [0.0,0.0]], + 1.0 => Vector{Float64}[[0.0,0.0], [1.0,-1.0], [2.0,3.0], [0.0,0.0]]) + return el +end + +function test_mock_element() test_element(MockElement) end -""" test adding fieldsets and fields to element""" function test_add_fields_to_element() - el = MockElement([1, 2, 3, 4]) - #geometry = Field([0.0, 0.0, 0.0, 0.0]) - el["geometry"] = Field([0.0, 0.0, 0.0, 0.0]) - @test el["geometry"][1].time == 0.0 - @test last(el["geometry"]) == [0.0, 0.0, 0.0, 0.0] - el["geometry"] = Field(Vector[[0.0, 0.0], [1.0, 0.0], [1.0, 1.0], [0.0, 1.0]]) - @test last(el["geometry"])[3] == [1.0, 1.0] - el["geometry"] = Vector[[0.0, 0.0], [1.0, 0.0], [1.0, 1.0], [0.0, 1.0]] - @test last(el["geometry"])[3] == [1.0, 1.0] - el["geometry"] = [0.0 0.0; 1.0 0.0; 1.0 1.0; 0.0 1.0]' - @test last(el["geometry"])[3] == [1.0, 1.0] - el["geometry"] = (0.0, [0.0, 0.0, 0.0, 0.0]), (1.0, [1.0, 1.0, 1.0, 1.0]) - field = el["geometry"] - @test length(field) == 2 # two time steps - el["boundary flux"] = (0.0, 0.0), (1.0, 6.0) + el = get_element() + info(el.fields) end -function test_add_fields_to_element_2() - el = MockElement([1, 2, 3, 4]) - el["data"] = (0.0 => [1, 2], 1.0 => [2, 3]) - @test length(el["data"]) == 2 - @test el["data"][1].time == 0.0 - @test el["data"][2].time == 1.0 - @test last(el["data"][1]) == [1, 2] - @test last(el["data"][2]) == [2, 3] +function test_interpolate() + el = get_element() + @test isapprox(el("geometry", [0.0, 0.0]), [0.5, 0.5]) + @test isapprox(el("geometry", [0.0, 0.0], 0.0), [0.5, 0.5]) + @test isapprox(el([0.0, 0.0]), [0.25 0.25 0.25 0.25]) + @test isapprox(el([0.0, 0.0], Val{:grad}), [-0.5 0.5 0.5 -0.5; -0.5 -0.5 0.5 0.5]) + gradT = el("temperature", [0.0, 0.0], 1.0, Val{:grad}) + info("gradT = $gradT") + X = [0.5, 0.5] + gradT_expected = [1-2*X[2] 3-2*X[1]] + info("gradT(expected) = $gradT_expected") + @test isapprox(gradT, gradT_expected) + + @test isapprox(el("temperature", [0.0, 0.0], 0.5), 1/2*gradT_expected) + + gradT = el("temperature", [0.0, 0.0], 0.5, Val{:grad}) + info("gradT = $gradT") + @test isapprox(gradT, 1/2*gradT_expected) end -function test_add_data_to_element_using_push() - el = MockElement([1, 2, 3, 4]) - el["data"] = [0, 0, 0, 0] - - push!(el["data"], [1, 2, 3, 4]) - @test length(el["data"]) == 1 - @test length(el["data"][1]) == 2 - @test el["data"][1].time == 0.0 - - push!(el["data"], 1.0 => [2, 3, 4, 5]) # creates new timestep at t=1.0 - push!(el["data"], [3, 4, 5, 6]) # adds new increment data to last timestep - @test length(el["data"]) == 2 - @test length(el["data"][2]) == 2 - @test el["data"][2].time == 1.0 - -end - -#= -facts("interpolation of fields in some function space") do - - el = MockElement([1, 2, 3, 4]) - fieldset1 = FieldSet("geometry", [Field(0.0, Vector[[0.0, 0.0], [1.0, 0.0], [1.0, 1.0], [0.0, 1.0]])]) - fieldset2 = FieldSet("constant scalar field", [Field(0.0, 1.0)]) - fieldset3 = FieldSet("scalar field", [Field(0.0, [1.0, 2.0, 3.0, 4.0])]) - fieldset4 = FieldSet("vector field 1", [Field(0.0, Vector[[1.0], [2.0], [3.0], [4.0]])]) - fieldset5 = FieldSet("vector field 2", [Field(0.0, Vector[[1.0, 5.0], [2.0, 6.0], [3.0, 7.0], [4.0, 8.0]])]) - fieldset6 = FieldSet("vector field 3", [Field(0.0, Vector[[1.0, 5.0, 9.0], [2.0, 6.0, 10.0], [3.0, 7.0, 11.0], [4.0, 8.0, 12.0]])]) - fieldset7 = FieldSet("tensor field 1", [Field(0.0, Matrix[[1.0 5.0; 9.0 13.0], [2.0 6.0; 10.0 14.0], [3.0 7.0; 11.0 15.0], [4.0 8.0; 12.0 16.0]])]) - - element["geometry"] = fieldset1 - element["constant scalar field"] = fieldset2 - element["scalar field"] = fieldset3 - element["vector field 1"] = fieldset4 - element["vector field 2"] = fieldset5 - element["vector field 3"] = fieldset6 - element["tensor field 1"] = fieldset7 - - xi = [0.0, 0.0] - t = 0.0 - u = FunctionSpace(element) - v = FunctionSpace(element) - - @fact v("constant scalar field", xi, t) --> 1.0 - @fact v("scalar field", xi, t) --> 1/4*(1+2+3+4) - @fact v("vector field 1", xi, t) --> [1/4*(1+2+3+4)] - @fact v("vector field 2", xi, t) --> 1/4*[1+2+3+4, 5+6+7+8] - @fact v("vector field 3", xi, t) --> 1/4*[1+2+3+4, 5+6+7+8, 9+10+11+12] - @fact v("tensor field 1", xi, t) --> 1/4*[1+2+3+4 5+6+7+8; 9+10+11+12 13+14+15+16] -end -=# - end diff --git a/test/test_solver.jl b/test/test_solver.jl index 567385f..c6e6e04 100644 --- a/test/test_solver.jl +++ b/test/test_solver.jl @@ -6,7 +6,7 @@ module SolverTests using JuliaFEM.Test using JuliaFEM -using JuliaFEM: DirichletProblem, Seg2, PlaneHeatProblem, Quad4, SimpleSolver, get_element, get_basis, MortarElement, MortarProblem, DirectSolver, PlaneStressElasticityProblem +using JuliaFEM: DirichletProblem, Seg2, PlaneHeatProblem, Quad4, SimpleSolver, get_element, get_basis, MortarElement, MortarProblem, PlaneStressElasticityProblem, solve!, DirectSolver """ Define Problem 1: @@ -38,7 +38,8 @@ end function get_boundaryproblem() el3 = Seg2([3, 4]) el3["geometry"] = Vector[[1.0, 1.0], [0.0, 1.0]] - problem2 = DirichletProblem(1) + el3["temperature"] = 0.0 + problem2 = DirichletProblem("temperature", 1) push!(problem2, el3) return problem2 end @@ -67,7 +68,7 @@ function test_simplesolver() @test isapprox(T, 100.0) end -function test_direct_solver() +function atest_direct_solver() N = Dict{Int, Vector}( 1 => [0.0, 0.0], @@ -87,7 +88,7 @@ function test_direct_solver() # volume elements e1 = Quad4([1, 2, 5, 4]) - e1["geometry"] = Vector[N[1], N[2], N[3], N[4]] + e1["geometry"] = Vector[N[1], N[2], N[5], N[4]] e2 = Quad4([2, 3, 6, 5]) e2["geometry"] = Vector[N[2], N[3], N[6], N[5]] e3 = Quad4([7, 8, 12, 11]) @@ -178,4 +179,56 @@ function test_direct_solver() end +function test_solver_multiple_dirichlet_bc() + N = Vector[[0.0, 0.0], [1.0, 0.0], [0.0, 1.0], [1.0, 1.0]] + + e1 = Quad4([1, 2, 4, 3]) + e1["geometry"] = Vector[N[1], N[2], N[4], N[3]] + e1["youngs modulus"] = 900.0 + e1["poissons ratio"] = 0.25 + b1 = Seg2([3, 4]) + b1["geometry"] = Vector[N[3], N[4]] + b1["displacement traction force"] = Vector[[0.0, -100.0], [0.0, -100.0]] + + #free_dofs = [3, 5, 6, 8] + free_dofs = [3, 6, 7, 8] + problem = PlaneStressElasticityProblem() + push!(problem, e1) + push!(problem, b1) + + # manually solve problem 1 + #solve!(problem, free_dofs, 0.0; max_iterations=10) + #disp = e1("displacement", [1.0, 1.0], 0.0) + #info("displacement at tip: $disp") + #@test isapprox(disp, [3.17431158889468E-02, -1.38591518927826E-01]) + + # boundary elements for dirichlet dx=0 + dx = Seg2([1, 3]) + dx["geometry"] = Vector[N[1], N[3]] + dx["displacement 1"] = 0.0 + + # boundary elements for dirichlet dy=0 + dy = Seg2([1, 2]) + dy["geometry"] = Vector[N[1], N[2]] + dy["displacement 2"] = 0.0 + + problem2 = DirichletProblem("displacement", 2) + push!(problem2, dx) + push!(problem2, dy) + + solver = DirectSolver() + push!(solver, problem) + push!(solver, problem2) + + # launch solver + norm = solver(0.0) + + disp = e1("displacement", [1.0, 1.0], 0.0) + info("displacement at tip: $disp") + @test isapprox(disp, [3.17431158889468E-02, -1.38591518927826E-01]) + +end + +# test_solver_multiple_dirichlet_bc() + end diff --git a/verification/2015-10-22-plane-stress/cplan_grot_gdep_traction_force.comm b/verification/2015-10-22-plane-stress/cplan_grot_gdep_traction_force.comm index 369a5b7..3388a1f 100644 --- a/verification/2015-10-22-plane-stress/cplan_grot_gdep_traction_force.comm +++ b/verification/2015-10-22-plane-stress/cplan_grot_gdep_traction_force.comm @@ -5,7 +5,7 @@ MAIL = LIRE_MAILLAGE() MO = AFFE_MODELE(MAILLAGE = MAIL, AFFE = _F(MAILLE=('E1', 'E2'), PHENOMENE='MECANIQUE', MODELISATION='C_PLAN')) -MAT = DEFI_MATERIAU(ELAS = _F(E=500.0, NU=0.3)) +MAT = DEFI_MATERIAU(ELAS = _F(E=900.0, NU=0.25)) CHMAT = AFFE_MATERIAU( MAILLAGE = MAIL, @@ -13,11 +13,13 @@ CHMAT = AFFE_MATERIAU( BC = AFFE_CHAR_MECA( MODELE = MO, - DDL_IMPO = (_F(NOEUD = ('N1','N4'), DX=0, DY=0))) + DDL_IMPO = ( + _F(NOEUD = ('N1','N2'), DY=0), + _F(NOEUD = ('N1','N4'), DX=0))) LO = AFFE_CHAR_MECA( MODELE = MO, - FORCE_CONTOUR = _F(MAILLE='E2', FY=-10.0)) + FORCE_CONTOUR = _F(MAILLE='E2', FY=-100.0)) LIST = DEFI_LIST_REEL( DEBUT = 0, diff --git a/verification/2015-10-22-plane-stress/cplan_grot_gdep_traction_force.mail b/verification/2015-10-22-plane-stress/cplan_grot_gdep_traction_force.mail index 7efcf07..24316da 100644 --- a/verification/2015-10-22-plane-stress/cplan_grot_gdep_traction_force.mail +++ b/verification/2015-10-22-plane-stress/cplan_grot_gdep_traction_force.mail @@ -1,8 +1,8 @@ COOR_2D N1 0.0 0.0 - N2 10.0 0.0 - N3 10.0 1.0 + N2 1.0 0.0 + N3 1.0 1.0 N4 0.0 1.0 FINSF diff --git a/verification/2015-10-22-plane-stress/cplan_grot_gdep_traction_force.resu b/verification/2015-10-22-plane-stress/cplan_grot_gdep_traction_force.resu index 4d6019c..3e33b4e 100644 --- a/verification/2015-10-22-plane-stress/cplan_grot_gdep_traction_force.resu +++ b/verification/2015-10-22-plane-stress/cplan_grot_gdep_traction_force.resu @@ -5,7 +5,7 @@ Version 11.4.0 du 05/06/2013 Copyright EDF R&D 1991 - 2015 - Exécution du : Tue Nov 17 23:07:16 2015 + Exécution du : Sun Nov 22 23:08:21 2015 Nom de la machine : jukka-desktop Architecture : 64bit Type de processeur : x86_64 @@ -37,13 +37,13 @@ Version de la librairie SCOTCH : 5.1.10 Mémoire limite pour l'exécution : 4096.00 Mo consommée par l'initialisation : 197.46 Mo - par les objets du jeu de commandes : 1.52 Mo + par les objets du jeu de commandes : 1.54 Mo reste pour l'allocation dynamique : 3897.01 Mo Taille limite des fichiers d'échange : 48.00 Go -------------------------------------------------------------------------------- - ASTER 11.04.00 CONCEPT RESU CALCULE LE 17/11/2015 A 23:07:16 DE TYPE EVOL_NOLI + ASTER 11.04.00 CONCEPT RESU CALCULE LE 22/11/2015 A 23:08:21 DE TYPE EVOL_NOLI ======> @@ -182,80 +182,80 @@ CHAMP AUX NOEUDS DE NOM SYMBOLIQUE DEPL NUMERO D'ORDRE: 1 INST: 1.00000000000000E+00 NOEUD DX DY - N1 -3.40638811414010E-24 2.68833699079734E-24 - N2 -5.55894020548543E+00 -8.54389686386317E+00 - N3 -4.37883078409381E+00 -9.33106637611714E+00 - N4 8.27180612553028E-25 -4.13590306276514E-25 + N1 8.26144597828415E-28 -6.46234853557053E-27 + N2 3.17431158889468E-02 -3.23117426778526E-27 + N3 3.17431158889468E-02 -1.38591518927826E-01 + N4 -1.61558713389263E-27 -1.38591518927826E-01 ------> CHAMP PAR ELEMENT AUX POINTS DE GAUSS DE NOM SYMBOLIQUE EPSI_ELGA NUMERO D'ORDRE: 1 INST: 1.00000000000000E+00 E1 EPXX EPYY EPZZ EPXY - 1 -5.30955374084645E-01 -1.66348491228137E-01 2.98844513705478E-01 -3.10819035435077E-01 - 2 -5.30955374084645E-01 -6.20821021025835E-01 4.93618455047349E-01 2.98492106217561E-02 - 3 -4.62821724873279E-01 -6.20821021025835E-01 4.64418319671049E-01 7.12558413187114E-03 - 4 -4.62821724873279E-01 -1.66348491228137E-01 2.69644378329178E-01 -3.33542661924962E-01 + 1 3.17431158889468E-02 -1.38591518927826E-01 3.56161343462932E-02 0.00000000000000E+00 + 2 3.17431158889468E-02 -1.38591518927826E-01 3.56161343462932E-02 6.93889390390723E-18 + 3 3.17431158889468E-02 -1.38591518927826E-01 3.56161343462932E-02 6.93889390390723E-18 + 4 3.17431158889468E-02 -1.38591518927826E-01 3.56161343462932E-02 -6.93889390390723E-18 ------> CHAMP PAR ELEMENT AUX NOEUDS DE NOM SYMBOLIQUE EPSI_ELNO NUMERO D'ORDRE: 1 INST: 1.00000000000000E+00 E1 EPXX EPYY EPZZ EPXY - N1 -5.55894020548543E-01 -8.32667268468867E-17 2.38240294520804E-01 -4.27194843193159E-01 - N2 -5.55894020548543E-01 -7.87169512253972E-01 5.75598656915364E-01 1.62859867502652E-01 - N3 -4.37883078409381E-01 -7.87169512253972E-01 5.25022538855723E-01 1.23501391889953E-01 - N4 -4.37883078409381E-01 -1.11022302462516E-16 1.87664176461163E-01 -4.66553318805857E-01 + N1 3.17431158889468E-02 -1.38591518927826E-01 3.56161343462932E-02 9.29635508958592E-19 + N2 3.17431158889468E-02 -1.38591518927826E-01 3.56161343462932E-02 8.54906983794366E-18 + N3 3.17431158889468E-02 -1.38591518927826E-01 3.56161343462932E-02 1.29481522988559E-17 + N4 3.17431158889468E-02 -1.38591518927826E-01 3.56161343462932E-02 -1.54879637418509E-17 ------> CHAMP PAR ELEMENT AUX POINTS DE GAUSS DE NOM SYMBOLIQUE SIEF_ELGA NUMERO D'ORDRE: 1 INST: 1.00000000000000E+00 E1 SIXX SIYY SIZZ SIXY - 1 -5.82089453243221E+01 1.60368493608182E+02 0.00000000000000E+00 -3.74379334332994E+01 - 2 1.77623597984452E+01 -1.73298174480217E+01 -2.25162844728429E-16 -1.06236006134150E+01 - 3 5.00553053519043E+01 1.15939930155404E+01 3.26087178768177E-15 -3.13335482197459E+01 - 4 -4.55341108580102E+01 2.29485076835540E+02 0.00000000000000E+00 -6.60541739958280E+01 + 1 -8.24861551021306E-15 -9.39413593841838E+01 0.00000000000000E+00 -5.61979191585450E-16 + 2 -1.64972310204261E-14 -9.39413593841838E+01 -8.24861551021306E-15 3.13823453049693E-15 + 3 1.05736540402492E-31 -9.39413593841838E+01 -8.24861551021306E-15 1.05263792435251E-15 + 4 8.24861551021306E-15 -9.39413593841838E+01 -8.24861551021306E-15 -2.64757579772987E-15 ------> CHAMP PAR ELEMENT AUX NOEUDS DE NOM SYMBOLIQUE SIGM_ELNO NUMERO D'ORDRE: 1 INST: 1.00000000000000E+00 E1 SIXX SIYY SIZZ SIXY - N1 -8.80273558499339E+01 1.94727353878533E+02 5.49455403429594E-16 -3.57191470178472E+01 - N2 3.11214204850306E+01 -8.75739524062778E+01 -2.05059548209250E-15 5.71225091278676E+00 - N3 9.94918269646633E+01 -6.29576400186074E+01 6.19745101666236E-15 -2.51460416790004E+01 - N4 -7.85112826317427E+01 3.39921984557592E+02 -1.66060199504612E-15 -9.02963184782274E+01 + N1 -1.12678183330014E-14 -9.39413593841838E+01 7.14351057789484E-15 -1.15297007340391E-15 + N2 -2.55548394887911E-14 -9.39413593841838E+01 -1.23729232653196E-14 5.25598809210632E-15 + N3 3.01920282278832E-15 -9.39413593841838E+01 -7.14351057789485E-15 1.64362880617097E-15 + N4 1.73062239785780E-14 -9.39413593841838E+01 -1.23729232653196E-14 -4.76532935933926E-15 ------> CHAMP AUX NOEUDS DE NOM SYMBOLIQUE FORC_NODA NUMERO D'ORDRE: 1 INST: 1.00000000000000E+00 NOEUD DX DY - N1 2.68987859445506E+02 -1.67866148841036E+02 - N2 -4.12787428844766E+00 4.17093399587432E+00 - N3 5.15024681990101E+00 -5.26887741319058E+01 - N4 -2.70010231976960E+02 2.16383988977067E+02 + N1 4.25199180137070E-15 4.84616754209406E+01 + N2 -4.50510868626231E-15 4.84616754209406E+01 + N3 9.52395007461808E-16 -4.84616754209406E+01 + N4 -6.99278122570202E-16 -4.84616754209406E+01 ------> CHAMP PAR ELEMENT AUX POINTS DE GAUSS DE NOM SYMBOLIQUE EPSG_ELGA NUMERO D'ORDRE: 1 INST: 1.00000000000000E+00 E1 EPXX EPYY EPZZ EPXY - 1 -1.06566987205140E-02 -1.21415776588635E-01 5.66024894182066E-02 -3.04578768594778E-01 - 2 -1.06566987205140E-02 5.01096016113645E-03 2.41960223973324E-03 5.31382035225386E-02 - 3 6.42405191820819E-02 5.01096016113645E-03 -2.96792054328079E-02 7.62286577556890E-02 - 4 6.42405191820819E-02 -1.21415776588635E-01 2.45036817456655E-02 -3.15026549152951E-01 + 1 3.22469285921163E-02 -1.28987714368465E-01 3.22469285921163E-02 5.77200597473660E-19 + 2 3.22469285921163E-02 -1.28987714368465E-01 3.22469285921164E-02 7.75012299681183E-18 + 3 3.22469285921164E-02 -1.28987714368465E-01 3.22469285921163E-02 8.23095891972260E-18 + 4 3.22469285921164E-02 -1.28987714368465E-01 3.22469285921163E-02 -5.88085738352280E-18 ------> CHAMP PAR ELEMENT AUX NOEUDS DE NOM SYMBOLIQUE EPSG_ELNO NUMERO D'ORDRE: 1 INST: 1.00000000000000E+00 E1 EPXX EPYY EPZZ EPXY - N1 -3.80709831456427E-02 -1.67691173956619E-01 8.81837816152549E-02 -4.27194843193159E-01 - N2 -3.80709831456428E-02 5.12863575291203E-02 -5.66373187863325E-03 1.71126738384121E-01 - N3 9.16548036072106E-02 5.12863575291203E-02 -6.12604976298561E-02 2.32382967145393E-01 - N4 9.16548036072106E-02 -1.67691173956619E-01 3.25870158640320E-02 -4.66553318805857E-01 + N1 3.22469285921163E-02 -1.28987714368465E-01 3.22469285921163E-02 1.24517756905760E-18 + N2 3.22469285921163E-02 -1.28987714368465E-01 3.22469285921164E-02 9.26996114254796E-18 + N3 3.22469285921164E-02 -1.28987714368465E-01 3.22469285921163E-02 1.45018758520459E-17 + N4 3.22469285921164E-02 -1.28987714368465E-01 3.22469285921163E-02 -1.43395894331661E-17 ------> @@ -276,34 +276,34 @@ CHAMP AUX NOEUDS DE NOM SYMBOLIQUE ENEL_NOEU NUMERO D'ORDRE: 1 INST: 1.00000000000000E+00 NOEUD TOTALE - N1 3.54914783015860E+01 - N2 -9.86342721345517E+00 - N3 -2.25443717206190E+01 - N4 1.13556696866632E+02 + N1 4.90276611274910E+00 + N2 4.90276611274910E+00 + N3 4.90276611274910E+00 + N4 4.90276611274910E+00 ------> CHAMP PAR ELEMENT CONSTANT SUR L'ELEMENT DE NOM SYMBOLIQUE ENEL_ELEM NUMERO D'ORDRE: 1 INST: 1.00000000000000E+00 E1 TOTALE - 2.91600940585360E+02 + 4.90276611274910E+00 ------> CHAMP PAR ELEMENT CONSTANT SUR L'ELEMENT DE NOM SYMBOLIQUE ETOT_ELEM NUMERO D'ORDRE: 1 INST: 1.00000000000000E+00 E1 TOTALE - 3.04350687094184E+01 + 6.50973784359943E+00 ------> CHAMP AUX NOEUDS DE NOM SYMBOLIQUE ETOT_NOEU NUMERO D'ORDRE: 1 INST: 1.00000000000000E+00 NOEUD TOTALE - N1 1.66816662962836E+01 - N2 3.28045573071458E+00 - N3 -3.38190091410633E+01 - N4 2.60309145978325E+01 + N1 6.50973784359943E+00 + N2 6.50973784359943E+00 + N3 6.50973784359943E+00 + N4 6.50973784359942E+00 FERMETURE DE LA BASE "GLOBALE" EFFECTUEE. @@ -312,32 +312,32 @@ MEMOIRE JEVEUX MINIMALE REQUISE POUR L'EXECUTION : 21.14 Mo MEMOIRE JEVEUX OPTIMALE REQUISE POUR L'EXECUTION : 27.32 Mo - MAXIMUM DE MEMOIRE UTILISEE PAR LE PROCESSUS LORS DE L'EXECUTION : 226.65 Mo + MAXIMUM DE MEMOIRE UTILISEE PAR LE PROCESSUS LORS DE L'EXECUTION : 226.66 Mo ******************************************************************************** * COMMAND : USER : SYSTEM : USER+SYS : ELAPSED * ******************************************************************************** - * init (jdc) : 0.17 : 0.01 : 0.18 : 0.20 * - * . compile : 0.01 : 0.00 : 0.01 : 0.00 * - * . exec_compile : 0.06 : 0.00 : 0.06 : 0.07 * + * init (jdc) : 0.15 : 0.02 : 0.17 : 0.17 * + * . compile : 0.00 : 0.00 : 0.00 : 0.00 * + * . exec_compile : 0.05 : 0.00 : 0.05 : 0.06 * * . report : 0.01 : 0.00 : 0.01 : 0.00 * * . build : 0.00 : 0.00 : 0.00 : 0.00 * - * DEBUT : 0.02 : 0.01 : 0.03 : 0.09 * - * LIRE_MAILLAGE : 0.01 : 0.00 : 0.01 : 0.10 * - * AFFE_MODELE : 0.00 : 0.00 : 0.00 : 0.17 * - * DEFI_MATERIAU : 0.00 : 0.00 : 0.00 : 0.01 * - * AFFE_MATERIAU : 0.01 : 0.00 : 0.01 : 0.00 * - * AFFE_CHAR_MECA : 0.00 : 0.00 : 0.00 : 0.05 * + * DEBUT : 0.01 : 0.02 : 0.03 : 0.04 * + * LIRE_MAILLAGE : 0.00 : 0.00 : 0.00 : 0.00 * + * AFFE_MODELE : 0.01 : 0.00 : 0.01 : 0.00 * + * DEFI_MATERIAU : 0.00 : 0.00 : 0.00 : 0.00 * + * AFFE_MATERIAU : 0.00 : 0.00 : 0.00 : 0.01 * + * AFFE_CHAR_MECA : 0.01 : 0.00 : 0.01 : 0.00 * * AFFE_CHAR_MECA : 0.00 : 0.00 : 0.00 : 0.00 * - * DEFI_LIST_REEL : 0.01 : 0.00 : 0.01 : 0.00 * - * DEFI_FONCTION : 0.00 : 0.00 : 0.00 : 0.00 * - * STAT_NON_LINE : 0.08 : 0.00 : 0.08 : 0.51 * - * CALC_CHAMP : 0.05 : 0.00 : 0.05 : 0.07 * - * IMPR_RESU : 0.01 : 0.00 : 0.01 : 0.07 * - * FIN : 0.01 : 0.02 : 0.03 : 0.03 * - * . part Superviseur : 0.20 : 0.02 : 0.22 : 0.41 * - * . part Fortran : 0.17 : 0.02 : 0.19 : 1.01 * + * DEFI_LIST_REEL : 0.00 : 0.00 : 0.00 : 0.00 * + * DEFI_FONCTION : 0.00 : 0.00 : 0.00 : 0.01 * + * STAT_NON_LINE : 0.06 : 0.00 : 0.06 : 0.06 * + * CALC_CHAMP : 0.04 : 0.00 : 0.04 : 0.04 * + * IMPR_RESU : 0.01 : 0.00 : 0.01 : 0.01 * + * FIN : 0.01 : 0.02 : 0.03 : 0.02 * + * . part Superviseur : 0.17 : 0.04 : 0.21 : 0.23 * + * . part Fortran : 0.14 : 0.02 : 0.16 : 0.14 * ******************************************************************************** - * TOTAL_JOB : 0.37 : 0.04 : 0.41 : 1.42 * + * TOTAL_JOB : 0.31 : 0.06 : 0.37 : 0.37 * ********************************************************************************