diff --git a/docs/src/man/solver/solver.md b/docs/src/man/solver/solver.md index c0caf9a2c..b2cc89951 100644 --- a/docs/src/man/solver/solver.md +++ b/docs/src/man/solver/solver.md @@ -142,3 +142,21 @@ If model reduction | ---------------- | ------------- | -------- | ------------------------------------------------------------------------- | | Type | String | No | Defines the type of model redction (Static Condensationn) | | Redcution Blocks | String or Int | No | Defines the blocks to be condensed; defintion are (4 or 1 2 4 or 1, 2, 4) | + + +## Computational effort + +A single-core performance comparison between the matrix-based solver +and the Verlet integrator for varying discretizations and horizon ratios $m = +\delta/\Delta x$ is shown in the table. All times in seconds. The sparsity pattern is a one-time preprocessing +cost and is excluded from the per-step effort in the last column. For the updated matrix algorithm this leads to a more efficient process. It was computed with v2.01 + +| Points | m | Assembly (s) | Solve (s) | Pattern (s) | Verlet (s) | Effort ratio incl. Pattern (−) | Effort ratio excl. Pattern (−) | +|--------:|---:|-------------:|----------:|------------:|-----------:|-------------------------------:|-------------------------------:| +| 160,801 | 2 | 3.10 | 19.60 | 3.83 | 0.234 | 113.4 | 97.0 | +| 40,401 | 2 | 0.80 | 4.23 | 1.00 | 0.040 | 150.8 | 125.8 | +| | 3 | 4.00 | 9.16 | 3.64 | 0.108 | 155.6 | 121.9 | +| | 4 | 12.30 | 19.80 | 8.56 | 0.129 | 315.2 | 248.8 | +| 10,201 | 2 | 0.19 | 0.52 | 0.15 | 0.012 | 71.7 | 59.2 | +| | 3 | 0.90 | 1.81 | 1.95 | 0.020 | 233.0 | 135.5 | +| | 4 | 2.98 | 2.31 | 2.50 | 0.071 | 109.7 | 74.5 | diff --git a/src/Core/Data_manager/data_manager_fields.jl b/src/Core/Data_manager/data_manager_fields.jl index d4d2716f3..f5640eeb8 100644 --- a/src/Core/Data_manager/data_manager_fields.jl +++ b/src/Core/Data_manager/data_manager_fields.jl @@ -42,7 +42,6 @@ Returns the field with the given name and time. - `field::Field`: The field with the given name and time. """ function get_field(name::String, time::String = "Constant") - @assert !occursin("NP1", name) if time == "Constant" return _get_field(name) elseif time == "N" @@ -130,8 +129,8 @@ function create_node_scalar_field(name::String, vartype::Type{T}; Bool}} set_NP1_to_N(name, vartype) - return _create_node_scalar_field(name * "N", T(default_value)), - _create_node_scalar_field(name * "NP1", T(default_value)) + return _create_node_scalar_field(data["NP1_to_N"][name].N, T(default_value)), + _create_node_scalar_field(data["NP1_to_N"][name].NP1, T(default_value)) end function create_constant_node_vector_field(name::String, vartype::Type{T}, dof::Int64; @@ -146,8 +145,8 @@ function create_node_vector_field(name::String, vartype::Type{T}, dof::Int64; Bool}} set_NP1_to_N(name, vartype) - return _create_node_vector_field(name * "N", T(default_value), dof), - _create_node_vector_field(name * "NP1", T(default_value), dof) + return _create_node_vector_field(data["NP1_to_N"][name].N, T(default_value), dof), + _create_node_vector_field(data["NP1_to_N"][name].NP1, T(default_value), dof) end function create_constant_node_tensor_field(name::String, vartype::Type{T}, dof::Int64; @@ -162,8 +161,8 @@ function create_node_tensor_field(name::String, vartype::Type{T}, dof::Int64; Bool}} set_NP1_to_N(name, vartype) - return _create_node_tensor_field(name * "N", T(default_value), dof), - _create_node_tensor_field(name * "NP1", T(default_value), dof) + return _create_node_tensor_field(data["NP1_to_N"][name].N, T(default_value), dof), + _create_node_tensor_field(data["NP1_to_N"][name].NP1, T(default_value), dof) end function create_constant_bond_scalar_state(name::String, vartype::Type{T}; @@ -178,8 +177,8 @@ function create_bond_scalar_state(name::String, vartype::Type{T}; Bool}} set_NP1_to_N(name, vartype) - return _create_bond_scalar_state(name * "N", T(default_value)), - _create_bond_scalar_state(name * "NP1", T(default_value)) + return _create_bond_scalar_state(data["NP1_to_N"][name].N, T(default_value)), + _create_bond_scalar_state(data["NP1_to_N"][name].NP1, T(default_value)) end function create_constant_bond_vector_state(name::String, vartype::Type{T}, dof::Int64; @@ -194,8 +193,8 @@ function create_bond_vector_state(name::String, vartype::Type{T}, dof::Int64; Bool}} set_NP1_to_N(name, vartype) - return _create_bond_vector_state(name * "N", T(default_value), dof), - _create_bond_vector_state(name * "NP1", T(default_value), dof) + return _create_bond_vector_state(data["NP1_to_N"][name].N, T(default_value), dof), + _create_bond_vector_state(data["NP1_to_N"][name].NP1, T(default_value), dof) end function create_constant_bond_tensor_state(name::String, vartype::Type{T}, dof::Int64; @@ -210,8 +209,8 @@ function create_bond_tensor_state(name::String, vartype::Type{T}, dof::Int64; Bool}} set_NP1_to_N(name, vartype) - return _create_bond_tensor_state(name * "N", T(default_value), dof), - _create_bond_tensor_state(name * "NP1", T(default_value), dof) + return _create_bond_tensor_state(data["NP1_to_N"][name].N, T(default_value), dof), + _create_bond_tensor_state(data["NP1_to_N"][name].NP1, T(default_value), dof) end function create_constant_element_vector_field(name::String, vartype::Type{T}, dof::Int64; @@ -232,8 +231,8 @@ function create_free_size_field(name::String, vartype::Type{T}, dof::Tuple; Bool}} set_NP1_to_N(name, vartype) - return _create_free_size_field(name * "N", T(default_value), dof), - _create_free_size_field(name * "NP1", T(default_value), dof) + return _create_free_size_field(data["NP1_to_N"][name].N, T(default_value), dof), + _create_free_size_field(data["NP1_to_N"][name].NP1, T(default_value), dof) end function create_field!(name::String, _data, field_type::String) diff --git a/src/Core/Data_manager/data_manager_solving_process.jl b/src/Core/Data_manager/data_manager_solving_process.jl index f39db7ee8..696eb7035 100644 --- a/src/Core/Data_manager/data_manager_solving_process.jl +++ b/src/Core/Data_manager/data_manager_solving_process.jl @@ -22,7 +22,7 @@ Sets the NP1_to_N dataset - `type`::Type The field type """ function set_NP1_to_N(name::String, ::Type{T}) where {T<:Union{Float64,Bool,Int64}} - if !has_key(name) + if !has_key(name * "N") data["NP1_to_N"][name] = NP1_to_N(name * "N", name * "NP1", zero(T)) end end @@ -36,6 +36,10 @@ end @inline function _fill_field_barrier(field_NP1, active::Vector{Bool}, np1_to_n::NP1_to_N{T}) where {T} + if isnothing(field_NP1) + @error "Field $(np1_to_n.NP1) not found. Cannot fill NP1 field from N." + return + end fill_field!(field_NP1, active, np1_to_n.value) end diff --git a/src/Core/Solver/Matrix_Verlet.jl b/src/Core/Solver/Matrix_Verlet.jl index be2f605d1..aa85ca0bf 100644 --- a/src/Core/Solver/Matrix_Verlet.jl +++ b/src/Core/Solver/Matrix_Verlet.jl @@ -43,37 +43,40 @@ function init_solver(solver_options::Dict{Any,Any}, @warn "Implementation might not work for MPI. Especially for coupling. It has to be tested." end find_bc_free_dof(bcs) - solver_options["Initial Time"] = get_initial_time(params) - solver_options["Final Time"] = get_final_time(params) - - solver_options["Number of Steps"] = get_nsteps(params) - - #solver_options["dt"] = (solver_options["Final Time"] - solver_options["Initial Time"]) / - # solver_options["Number of Steps"] + initial_time = get_initial_time(params) + final_time = get_final_time(params) + nsteps = get_nsteps(params) mechanical = "Material" in solver_options["Models"] thermal = "Thermal" in solver_options["Models"] solver_options["dt"] = compute_crititical_time_step(block_nodes, mechanical, thermal) #solver_options["dt"] = 1e-8 - solver_options["Number of Steps"] = Int(ceil((solver_options["Final Time"] - - solver_options["Initial Time"]) / - solver_options["dt"])) - K = Data_Manager.get_stiffness_matrix() - if isnothing(K) - for (block, nodes) in pairs(block_nodes) - model_param = Data_Manager.get_properties(block, "Material Model") - Correspondence_matrix_based.init_model(nodes, model_param, block) - end - @timeit "init_matrix" Correspondence_matrix_based.init_matrix() - K = Data_Manager.get_stiffness_matrix() + safety_factor = get_safety_factor(params) + fixed_dt = get_fixed_dt(params) + min_dt = compute_crititical_time_step(block_nodes, mechanical, thermal) + if fixed_dt == -1.0 + nsteps_temp, + dt = get_integration_steps(initial_time, final_time, + safety_factor * min_dt) + else + nsteps_temp, dt = get_integration_steps(initial_time, final_time, fixed_dt) + end + if nsteps == 1 + nsteps = nsteps_temp end + + K = Data_Manager.get_stiffness_matrix() + dof = Data_Manager.get_dof() density = Data_Manager.get_field("Density") model_reduction = get(params["Verlet Matrix Based"], "Model Reduction", false) solver_options["Model Reduction"] = model_reduction solver_options["Numerical Damping"] = get_numerical_damping(params) - + solver_options["dt"] = dt + solver_options["Initial Time"] = initial_time + solver_options["Final Time"] = final_time + solver_options["Number of Steps"] = nsteps @info "Solver parameter" @info "Initial Time: $(solver_options["Initial Time"])" @info "Final Time: $(solver_options["Final Time"])" @@ -104,7 +107,7 @@ function init_solver(solver_options::Dict{Any,Any}, else # might lead to issues, because neighbors outside the block are included in for block in eachindex(block_nodes) - block_nodes[block] = [] + Data_Manager.set_reduced_model_pd(Vector{Int64}([])) end @warn "No other models work with full matrix Verlet right now." end @@ -113,8 +116,9 @@ function init_solver(solver_options::Dict{Any,Any}, master_nodes = Int64[] slave_nodes = Int64[] pd_nodes = Int64[] - temp = [] + nlist = Data_Manager.get_nlist() + # only for visualization and debugging. cn = Data_Manager.create_constant_node_scalar_field("Coupling Nodes", Int64) full_blocks = setdiff(collect(keys(block_nodes)), reduction_blocks) for block in full_blocks @@ -128,60 +132,58 @@ function init_solver(solver_options::Dict{Any,Any}, append!(master_nodes, pd_nodes) master_nodes = sort(unique(master_nodes)) - coupling_nodes = setdiff(unique(master_nodes), pd_nodes) - for node in coupling_nodes - append!(temp, nlist[node]) - end - append!(coupling_nodes, temp) - slave_nodes = setdiff(1:Data_Manager.get_nnodes(), unique(master_nodes)) - cn[slave_nodes] .= 6 - cn[master_nodes] .= 2 - cn[pd_nodes] .= 1 + slave_nodes = sort(setdiff(1:Data_Manager.get_nnodes(), master_nodes)) - for block in eachindex(block_nodes) - intersect!(block_nodes[block], pd_nodes) + if !(get(solver_options["Model Reduction"], "Material Point Region", true)) + pd_nodes::Vector{Int64} = [] end - + sort!(pd_nodes) + if isnothing(K) + for (block, nodes) in pairs(block_nodes) + model_param = Data_Manager.get_properties(block, "Material Model") + Correspondence_matrix_based.init_model(nodes, model_param, block) + end + @timeit "init_matrix" Correspondence_matrix_based.init_matrix() + end + if pd_nodes != [] + nodes = setdiff(collect(1:Data_Manager.get_nnodes()), pd_nodes) + @timeit "update_material_point_part" Correspondence_matrix_based.compute_model(nodes) + end + K = Data_Manager.get_stiffness_matrix() if !(master_nodes == []) + coupling_nodes = setdiff(master_nodes, pd_nodes) + + cn[master_nodes] .= 3 + cn[slave_nodes] .= 6 + cn[pd_nodes] .+= 1 # added to be sure that all points are handled + cn[coupling_nodes] .+= 3 # added to be sure that all points are handled + nnodes = Data_Manager.get_nnodes() - # complete region of analysis with coupling + perm_master = create_permutation(master_nodes, Data_Manager.get_dof(), nnodes) - # complete region of reduction perm_slave = create_permutation(slave_nodes, Data_Manager.get_dof(), nnodes) - - # indices of pd nodes in global system of PD nodes for crack propagation and BCs application perm_pd_nodes = create_permutation(pd_nodes, Data_Manager.get_dof(), nnodes) - # indices of deletes in global system - # create reduced M^-1*K for linear run - #TODO adapt for mass matrix - density_mass = zeros(length(density) * Data_Manager.get_dof()) - @warn "Constant mass density for model reduction is assumed." - density_mass .= density[1] - # find indices of pd nodes and coupling nodes in reduced system; using master ids vector + perm_coupling_nodes = create_permutation(coupling_nodes, Data_Manager.get_dof(), + nnodes) + + # create permutations in the reduced system; only master nodes exist. PD and overlap nodes are part of the master nodes and get the indices of the master nodes in the reduced system. + # Sorting is important to ensure that the order of the nodes in the reduced system is the same as in the original system perm_pd_reduced = findall(in(perm_pd_nodes), perm_master) + perm_coupling_reduced = findall(in(perm_coupling_nodes), perm_master) + # create the mass part. + density_mass = zeros(length(density) * dof) + for iID in eachindex(density_mass) + density_mass[iID] = density[Int(ceil(iID / dof))] + end + # perform the condensation of the system + @timeit "Guyan Condensation" K_reduced, + mass_reduced=guyan_reduction(K, + density_mass, + perm_master, + perm_slave) - @timeit "gyan" K_reduced, - mass_reduced=guyan_reduction(K, density_mass, - perm_master, perm_slave) - # - # K_reduced[:, perm_pd_reduced] .= 0 - K_reduced[perm_pd_reduced, :] .= 0 - - #for pd in perm_pd_reduced - # mass_reduced[pd,:].=0.0 - # mass_reduced[:,pd].=0.0 - # mass_reduced[pd,pd]=density[1] - #end dropzeros!(mass_reduced) - - # K_reduced[perm_delete_reduced, perm_delete_reduced] .= 0 - - #-> der Rest der keine cn als nachbarn hat; cn reduced einfach nur multipl. - - # K_reduced[:, perm_cn_reduced] .= 0 - # @info length(perm_delete_reduced), length(perm_pd_reduced) - # readline() dropzeros!(K_reduced) Data_Manager.set_stiffness_matrix(sparse(K_reduced)) @@ -196,26 +198,22 @@ function init_solver(solver_options::Dict{Any,Any}, end @warn "No master nodes defined for model reduction. Using full stiffness matrix." end - - # create M^-1*K for linear run - #for (block, nodes) in pairs(block_nodes) - # for node in nodes - # for idof in 1:dof - # K[(node-1)*dof+idof, (node-1)*dof+idof]/=density[node] - # end - # end - #end - + if isnothing(K) + for (block, nodes) in pairs(block_nodes) + model_param = Data_Manager.get_properties(block, "Material Model") + Correspondence_matrix_based.init_model(nodes, model_param, block) + end + @timeit "init_matrix" Correspondence_matrix_based.init_matrix() + K = Data_Manager.get_stiffness_matrix() + end density_mass = zeros(length(density) * Data_Manager.get_dof()) - @warn "TBD Constant mass density for matrix modelis assumed." - density_mass .= density[1] + for iID in eachindex(density_mass) + density_mass[iID] = density[Int(ceil(iID / dof))] + end mass = Diagonal(density_mass) perm = collect(1:(Data_Manager.get_nnodes() * Data_Manager.get_dof())) Data_Manager.set_mass_matrix(lu(sparse(mass[perm, perm]))) return - - # reduced matrix - end function run_solver(solver_options::Dict{Any,Any}, @@ -237,8 +235,6 @@ function run_solver(solver_options::Dict{Any,Any}, max_damage::Float64 = 0 damage_init::Bool = false - density::NodeScalarField{Float64} = Data_Manager.get_field("Density") - coor::NodeVectorField{Float64} = Data_Manager.get_field("Coordinates") active_list::NodeScalarField{Bool} = Data_Manager.get_field("Active") @@ -257,12 +253,12 @@ function run_solver(solver_options::Dict{Any,Any}, if solver_options["Model Reduction"] != false master_nodes = Data_Manager.get_reduced_model_master() temp = zeros(length(master_nodes) * Data_Manager.get_dof()) + else temp = zeros(Data_Manager.get_dof() * Data_Manager.get_nnodes()) end - K::AbstractMatrix{Float64} = Data_Manager.get_stiffness_matrix() - #nodes::Vector{Int64} = Vector{Int64}(1:Data_Manager.get_nnodes()) + K::AbstractMatrix{Float64} = Data_Manager.get_stiffness_matrix() @timeit "Matrix Verlet" begin @inbounds @fastmath for idt in iter @@ -281,6 +277,7 @@ function run_solver(solver_options::Dict{Any,Any}, if solver_options["Model Reduction"] != false active_nodes = master_nodes active_list .= false + # coupling region and material point region must be active. shown in symbolic code. active_list[Data_Manager.get_reduced_model_pd()] .= true else @@ -303,53 +300,36 @@ function run_solver(solver_options::Dict{Any,Any}, time, step_time) #-> Dirichlet @timeit "deformed coor" @views deformed_coorNP1 .= coor .+ uNP1 - # thermal model, usw. - - #mul!(a[active_nodes], K[active_nodes, active_nodes], uNP1[active_nodes]) - - @timeit "sa" sa=size(a[active_nodes, :]) @timeit "compute models" compute_models(block_nodes, dt, time, solver_options["Models"], synchronise_field) - #force_densities_NP1[active_nodes, :] .*= volume[active_nodes] @timeit "Force computations" begin - # check if valid if volume is different - - #-= f_int(K, - # vec(uNP1[active_nodes, - # :]), sa) - # hier muss pd nodes rein + @timeit "sa" sa=size(a[active_nodes, :]) - #1D testen @views fNP1 = force_densities_NP1[active_nodes, :] @timeit "Force matrix computations" f_int_inplace!(fNP1, temp, K, vec(uNP1[active_nodes, :]), sa) - @. @views fNP1 .+= external_force_densities[active_nodes, - :] + - external_forces[active_nodes, - :] / volume[active_nodes] + @. @views fNP1 .+= external_force_densities[active_nodes, :] + + external_forces[active_nodes, :] / volume[active_nodes] - @. @views forces[active_nodes, :] .= force_densities_NP1[active_nodes, :] * - volume[active_nodes] + - external_forces[active_nodes, :] + @. @views forces[active_nodes, :] .= fNP1 * + volume[active_nodes] + check_inf_or_nan(force_densities_NP1, "Force Densities") end @timeit "Accelaration computation" begin @views a[active_nodes, :] = reshape(M_fact \ - vec(force_densities_NP1[active_nodes, - :]), + vec(fNP1), sa...) end @timeit "write_results" result_files=write_results(result_files, time, max_damage, outputs) - # for file in result_files - # flush(file) - # end + if rank == 0 && !silent && Data_Manager.get_cancel() set_multiline_postfix(iter, "Simulation canceled!") break @@ -366,10 +346,7 @@ function run_solver(solver_options::Dict{Any,Any}, if rank == 0 && !silent set_postfix(iter, t = @sprintf("%.3e", time)) end - - # barrier(comm) end - #a+= + fexternal / density end end Data_Manager.set_current_time(time - dt) @@ -384,4 +361,32 @@ function f_int_inplace!(F::AbstractMatrix{Float64}, F .+= reshape(temp, sa) end +""" + get_integration_steps(initial_time::Float64, end_time::Float64, dt::Float64) + +Calculate the number of integration steps and the adjusted time step for a numerical integration process. + +# Arguments +- `initial_time::Float64`: The initial time for the integration. +- `end_time::Float64`: The final time for the integration. +- `dt::Float64`: The time step size. + +# Returns +A tuple `(nsteps, dt)` where: +- `nsteps::Int64`: The number of integration steps required to cover the specified time range. +- `dt::Float64`: The adjusted time step size to evenly divide the time range. + +# Errors +- Throws an error if the `dt` is less than or equal to zero. +""" +function get_integration_steps(initial_time::Float64, end_time::Float64, dt::Float64) + if !(0 < dt < 1e50) + @error "Time step $dt [s] is not valid" + return nothing + end + nsteps::Int64 = ceil((end_time - initial_time) / dt) + dt = (end_time - initial_time) / nsteps + return nsteps, dt +end + end diff --git a/src/Core/Solver/Matrix_linear_static.jl b/src/Core/Solver/Matrix_linear_static.jl index ef10c02a0..b780eccf7 100644 --- a/src/Core/Solver/Matrix_linear_static.jl +++ b/src/Core/Solver/Matrix_linear_static.jl @@ -245,7 +245,7 @@ function run_solver(solver_options::Dict{Any,Any}, all_nodes_active = length(active_nodes) == nnodes non_BCs_global = Data_Manager.get_bc_free_dof() - + @info "Static time increment: $dt" for idt in iter Data_Manager.set_iteration(idt) @timeit "Linear Static" begin @@ -382,7 +382,7 @@ function run_solver(solver_options::Dict{Any,Any}, # Update forces for all nodes @inbounds for iID in nodes for d in 1:dof - forces[iID, d] = force_densities_NP1[iID, d] * volume[iID] + forces[iID, d] += force_densities_NP1[iID, d] .* volume[iID] end end end @@ -479,12 +479,12 @@ function compute_displacements_active_subset!(K_active::AbstractMatrix{Float64}, # Build modified force vector (same as reference) @inbounds for (idx, i) in enumerate(active_non_BCs) - solver.F_modified[idx] = F_ext_vec[i] - F_int_vec[i] + solver.F_modified[idx] = -F_ext_vec[i] - F_int_vec[i] end # LU factorization and solve (same as reference) @timeit "LU factorization" begin - K_free = K_active[active_non_BCs, active_non_BCs] + K_free = sparse(K_active[active_non_BCs, active_non_BCs]) try solver.K_free_lu = lu(K_free) catch e @@ -507,97 +507,6 @@ function compute_displacements_active_subset!(K_active::AbstractMatrix{Float64}, return nothing end -# Neue Hilfsfunktion für reduziertes System -# function compute_displacements_reduced!(K_active::AbstractMatrix{Float64}, -# active_non_BCS::AbstractVector{Int}, -# u_active::AbstractVector{Float64}, -# F_int_active::AbstractVector{Float64}, -# F_ext_active::AbstractVector{Float64}, -# solver::DisplacementSolverCache) -# isempty(active_non_BCS) && return nothing - -# n_total = length(u_active) -# n_free = length(active_non_BCS) - -# length(solver.F_modified) != n_free && resize!(solver.F_modified, n_free) -# length(solver.bc_mask) != n_total && resize!(solver.bc_mask, n_total) - -# has_BCs = n_free < n_total - -# if has_BCs -# fill!(solver.bc_mask, true) -# @inbounds for i in active_non_BCS -# solver.bc_mask[i] = false -# end - -# K_sub = K_active[active_non_BCS, solver.bc_mask] -# u_bc = @view u_active[solver.bc_mask] - -# length(solver.temp) != n_free && resize!(solver.temp, n_free) -# mul!(solver.temp, K_sub, u_bc) - -# @inbounds for (idx, i) in enumerate(active_non_BCS) -# F_int_active[i] += solver.temp[idx] -# end -# end - -# @inbounds for (idx, i) in enumerate(active_non_BCS) -# solver.F_modified[idx] = F_ext_active[i] - F_int_active[i] -# end - -# # LU factorization -# @timeit "LU factorization" begin -# K_free = K_active[active_non_BCS, active_non_BCS] -# try -# solver.K_free_lu = lu(K_free) -# catch e -# @error "LU factorization failed: $e" -# @error "Matrix size: $(size(K_free))" -# @error "Condition number: $(cond(K_free))" -# rethrow(e) -# end -# end - -# length(solver.u_free) != n_free && resize!(solver.u_free, n_free) - -# @timeit "ldiv" ldiv!(solver.u_free, solver.K_free_lu, solver.F_modified) - -# @inbounds for (idx, i) in enumerate(active_non_BCS) -# u_active[i] = solver.u_free[idx] -# end - -# return nothing -# end - -# function get_active_dof(active_nodes::AbstractVector{Int64}, dof::Int64, nnodes::Int64) -# n_active = length(active_nodes) - -# active_dofs_local = collect(1:(n_active * dof)) -# local_to_global = Dict{Int,Int}() - -# for (iD, global_iD) in enumerate(active_nodes) -# for j in 1:dof -# local_idx = iD + (j - 1) * n_active -# global_idx = global_iD + (j - 1) * nnodes -# local_to_global[local_idx] = global_idx -# end -# end - -# return active_dofs_local, local_to_global -# end - -# function filter_and_map_bc(non_BCs_global::AbstractVector{Int64}, -# local_to_global::Dict{Int,Int}) -# active_non_BCs_local = Int[] - -# for (local_idx, global_idx) in pairs(local_to_global) -# if global_idx in non_BCs_global -# push!(active_non_BCs_local, local_idx) -# end -# end - -# return sort(active_non_BCs_local) -# end function compute_matrix(nodes::AbstractVector{Int64}) if length(nodes) == 0 return Data_Manager.get_stiffness_matrix() @@ -693,7 +602,15 @@ function compute_displacements!(K::AbstractMatrix{Float64}, @inbounds for (idx, i) in enumerate(active_non_BCS) u_vec[i] = solver.u_free[idx] end - + if has_BCs + bc_dofs = findall(solver.bc_mask) + # K_active[bc_dofs, :] * u_vec = K_bc,free * u_free + K_bc,bc * u_bc + K_bc_rows = K_active[bc_dofs, :] # braucht vollständige K_active + r_bc = K_bc_rows * u_vec # u_vec ist jetzt vollständig + @inbounds for (idx, i) in enumerate(bc_dofs) + F_int_vec[i] = r_bc[idx] - F_ext_vec[i] + end + end return nothing end diff --git a/src/Core/Solver/Verlet_solver.jl b/src/Core/Solver/Verlet_solver.jl index 87066df99..fc4ec2455 100644 --- a/src/Core/Solver/Verlet_solver.jl +++ b/src/Core/Solver/Verlet_solver.jl @@ -325,7 +325,7 @@ function run_solver(solver_options::Dict{Any,Any}, active_nodes = find_active_nodes(active_list, active_nodes, 1:Data_Manager.get_nnodes()) if "Material" in solver_options["Models"] - check_inf_or_nan(force_densities, "Forces") + check_inf_or_nan(force_densities, "Force Densities") if fem_option # edit external force densities won't work so easy, because the corresponded volume is in detJ diff --git a/src/Models/Material/Material_Models/Correspondence/Correspondence.jl b/src/Models/Material/Material_Models/Correspondence/Correspondence.jl index f1bd61987..e3ebedf7c 100644 --- a/src/Models/Material/Material_Models/Correspondence/Correspondence.jl +++ b/src/Models/Material/Material_Models/Correspondence/Correspondence.jl @@ -21,7 +21,7 @@ include("./Bond_Associated_Correspondence.jl") using .Bond_Associated_Correspondence using ....Material_Basis: compute_Piola_Kirchhoff_stress! using .......Helpers: invert, rotate, determinant, smat, matrix_diff!, fast_mul!, mat_mul! -using .......Geometry: compute_strain! +using .......Geometry: compute_strain!, compute_linear_strain! export init_model export material_name @@ -49,8 +49,10 @@ function init_model(nodes::AbstractVector{Int64}, end dof = Data_Manager.get_dof() Data_Manager.create_node_tensor_field("Strain", Float64, dof) + Data_Manager.create_constant_node_tensor_field("Strain Increment", Float64, dof) Data_Manager.create_node_tensor_field("Cauchy Stress", Float64, dof) + Data_Manager.create_node_scalar_field("von Mises Stress", Float64) rotation::Bool = Data_Manager.get_rotation() material_models = split(material_parameter["Material Model"], "+") @@ -173,10 +175,15 @@ function compute_correspondence_model(nodes::AbstractVector{Int64}, stress_NP1::NodeTensorField{Float64} = Data_Manager.get_field("Cauchy Stress", "NP1") strain_increment::NodeTensorField{Float64} = Data_Manager.get_field("Strain Increment") - @timeit "compute strain" compute_strain!(nodes, deformation_gradient, strain_NP1) + if haskey(material_parameter, "Linear Strain") && material_parameter["Linear Strain"] + @timeit "compute linear strain" compute_linear_strain!(nodes, deformation_gradient, + strain_NP1) + else + @timeit "compute strain" compute_strain!(nodes, deformation_gradient, strain_NP1) + end @timeit "compute matrix diff" matrix_diff!(strain_increment, nodes, strain_NP1, strain_N) - + #@error "" if rotation @timeit "rotate forward" begin rotation_tensor::NodeTensorField{Float64} = Data_Manager.get_field("Rotation Tensor") diff --git a/src/Models/Material/Material_Models/Correspondence/Correspondence_Elastic.jl b/src/Models/Material/Material_Models/Correspondence/Correspondence_Elastic.jl index 99b5fa1b3..78eb7c1d1 100644 --- a/src/Models/Material/Material_Models/Correspondence/Correspondence_Elastic.jl +++ b/src/Models/Material/Material_Models/Correspondence/Correspondence_Elastic.jl @@ -45,7 +45,8 @@ Initializes the material model. function init_model(nodes::AbstractVector{Int64}, material_parameter::Dict) dof::Int64 = Data_Manager.get_dof() - hooke_matrix::NodeTensorField{Float64} = Data_Manager.create_constant_node_tensor_field("Elasticity Matrix", + + hooke_matrix::NodeTensorField{Float64} = Data_Manager.create_constant_node_tensor_field("Material Gradient", Float64, Int64((dof * (dof + @@ -119,7 +120,7 @@ function compute_stresses(nodes::AbstractVector{Int64}, get_mapping(dof) end - hooke_matrix::NodeTensorField{Float64} = Data_Manager.get_field("Elasticity Matrix") + hooke_matrix::NodeTensorField{Float64} = Data_Manager.get_field("Material Gradient") @inbounds for iID in nodes # Voigt-Notation @@ -131,8 +132,11 @@ function compute_stresses(nodes::AbstractVector{Int64}, # Constitutive Relation: σ_ij^(n+1) = σ_ij^n + C_ijkl * Δε_kl for k in axes(mapping, 1) + i_k = mapping[k, 1] + j_k = mapping[k, 2] + factor = (i_k == j_k) ? 1.0 : 2.0 # Voigt: γ = 2ε für Schub sNP1 += hooke_matrix[iID, m, k] * - strain_increment[iID, mapping[k, 1], mapping[k, 2]] + factor * strain_increment[iID, i_k, j_k] end stress_NP1[iID, i, j] = sNP1 diff --git a/src/Models/Material/Material_Models/Correspondence/Correspondence_UMAT.jl b/src/Models/Material/Material_Models/Correspondence/Correspondence_UMAT.jl index b8ecd9f04..eaa05e8e0 100644 --- a/src/Models/Material/Material_Models/Correspondence/Correspondence_UMAT.jl +++ b/src/Models/Material/Material_Models/Correspondence/Correspondence_UMAT.jl @@ -7,8 +7,7 @@ using StaticArrays using ......Data_Manager using ......Helpers: voigt_to_matrix, matrix_to_voigt -using .....Material_Basis: get_Hooke_matrix -#using .....Global_Zero_Energy_Control: global_zero_energy_mode_stiffness +using .....Material_Basis: get_Hooke_matrix, get_all_elastic_moduli export fe_support export init_model export correspondence_name @@ -53,14 +52,14 @@ function init_model(nodes::AbstractVector{Int64}, num_state_vars::Int64 = 1 if !haskey(material_parameter, "File") @error "UMAT file is not defined." - return + return 1 end directory = Data_Manager.get_directory() material_parameter["File"] = joinpath(pwd(), directory, material_parameter["File"]) global umat_file_path = material_parameter["File"] if !isfile(material_parameter["File"]) @error "File $(material_parameter["File"]) does not exist, please check name and directory." - return + return 1 end if haskey(material_parameter, "Number of State Variables") num_state_vars = material_parameter["Number of State Variables"] @@ -75,7 +74,7 @@ function init_model(nodes::AbstractVector{Int64}, if !haskey(material_parameter, "Number of Properties") @error "Number of Properties must be at least equal 1" - return + return 1 end # properties include the material properties, etc. num_props = material_parameter["Number of Properties"] @@ -121,6 +120,14 @@ function init_model(nodes::AbstractVector{Int64}, DRPLDT = Data_Manager.create_constant_node_scalar_field("Variation of RPL with respect to the temperature", Float64) DFGRD0 = Data_Manager.create_constant_node_tensor_field("DFGRD0", Float64, dof) + + DDSDDE::NodeTensorField{Float64} = Data_Manager.create_constant_node_tensor_field("Material Gradient", + Float64, + Int64((dof * + (dof + + 1)) / + 2)) + # is already initialized if thermal problems are adressed Data_Manager.create_node_scalar_field("Temperature", Float64) deltaT = Data_Manager.create_constant_node_scalar_field("Delta Temperature", Float64) @@ -157,6 +164,16 @@ function init_model(nodes::AbstractVector{Int64}, zStiff = Data_Manager.create_constant_node_tensor_field("Zero Energy Stiffness", Float64, dof) + get_all_elastic_moduli(material_parameter) + symmetry::String = get(material_parameter, "Symmetry", "default") + + for iID in nodes + @views DDSDDE[iID, :, + :] = get_Hooke_matrix(material_parameter, + symmetry, + dof, + iID) + end end """ @@ -217,7 +234,11 @@ function compute_stresses(nodes::AbstractVector{Int64}, statev = Data_Manager.get_field("State Variables") stress_temp::Vector{Float64} = zeros(Float64, 3 * dof - 3) - DDSDDE = zeros(Float64, 3 * dof - 3, 3 * dof - 3) + # DDSDDE = zeros(Float64, 3 * dof - 3, 3 * dof - 3) + ## TODO use C_voigt = Data_Manager.get_field("Material Gradient") + DDSDDE_iD = Data_Manager.get_field("Material Gradient") + # + ## SSE = Data_Manager.get_field("Specific Elastic Strain Energy") SPD = Data_Manager.get_field("Specific Plastic Dissipation") SCD = Data_Manager.get_field("Specific Creep Dissipation Energy") @@ -268,6 +289,7 @@ function compute_stresses(nodes::AbstractVector{Int64}, DDSDDT_temp = DDSDDT[iID, :] DRPLDE_temp = DRPLDE[iID, :] DRPLDT_temp = DRPLDT[iID] + DDSDDE = DDSDDE_iD[iID, :, :] UMAT_interface(stress_temp, STATEV_temp, DDSDDE, diff --git a/src/Models/Material/Material_Models/Correspondence/Correspondence_matrix_based.jl b/src/Models/Material/Material_Models/Correspondence/Correspondence_matrix_based.jl index 648a3d57e..e0aaa8138 100644 --- a/src/Models/Material/Material_Models/Correspondence/Correspondence_matrix_based.jl +++ b/src/Models/Material/Material_Models/Correspondence/Correspondence_matrix_based.jl @@ -228,7 +228,7 @@ for O(1) direct writes in the assembly loop. The sparsity pattern includes all (iID, jID) pairs where jID ∈ nlist[iID], covering both the node itself and all its neighbors. -""" + function build_sparsity_and_map(nodes::AbstractVector{Int}, nlist::Vector{Vector{Int}}, number_of_neighbors::Vector{Int}, @@ -290,6 +290,66 @@ function build_sparsity_and_map(nodes::AbstractVector{Int}, return K, colptr, rowval end +""" + +function build_sparsity_and_map(nodes::AbstractVector{Int}, + nlist::Vector{Vector{Int}}, + number_of_neighbors::Vector{Int}, + nnodes::Int, + dof::Int) + n = dof * nnodes + + # pro Spalte: Menge eindeutiger Zeilen + col_rows = [Set{Int}() for _ in 1:n] + + @inbounds for iID in nodes + nj = nlist[iID] + mnj = number_of_neighbors[iID] + + local_nodes = (nj..., iID) # Nachbarn + eigener Knoten + + for row_node in local_nodes + for m in 1:dof + grow = (m - 1) * nnodes + row_node + + for col_node in local_nodes + for o in 1:dof + gcol = (o - 1) * nnodes + col_node + push!(col_rows[gcol], grow) + end + end + end + end + end + + # CSC aufbauen + colptr = Vector{Int}(undef, n + 1) + colptr[1] = 1 + + sorted_cols = Vector{Vector{Int}}(undef, n) + + @inbounds for col in 1:n + v = collect(col_rows[col]) + sort!(v) + sorted_cols[col] = v + colptr[col + 1] = colptr[col] + length(v) + end + + nnz_total = colptr[end] - 1 + rowval = Vector{Int}(undef, nnz_total) + nzval_arr = fill(eps(), nnz_total) + + @inbounds for col in 1:n + v = sorted_cols[col] + start = colptr[col] + rowval[start:(start + length(v) - 1)] .= v + end + + K = SparseMatrixCSC(n, n, colptr, rowval, nzval_arr) + + return K, colptr, rowval +end + # ============================================================================= # Main assembly # ============================================================================= @@ -522,7 +582,7 @@ function init_matrix(use_block_style::Bool = true, include_zero_energy::Bool = t number_of_neighbors = Data_Manager.get_field("Number of Neighbors") volume = Data_Manager.get_field("Volume") omega = Data_Manager.get_field("Influence Function") - C_voigt = Data_Manager.get_field("Elasticity Matrix") + C_voigt = Data_Manager.get_field("Material Gradient") bond_damage = Data_Manager.get_field("Bond Damage", "NP1") C_voigt_trafo = _apply_rotation(C_voigt, dof, nnodes) @@ -557,7 +617,7 @@ function init_matrix(use_block_style::Bool = true, include_zero_energy::Bool = t bond_geometry, omega, bond_damage, zStiff) - Data_Manager.set_stiffness_matrix(-K_sparse) + Data_Manager.set_stiffness_matrix(-K_sparse) # somewhere in the assembly we had a factor of 0.5, so we compensate here to get the final K end function compute_model(nodes::AbstractVector{Int64}, @@ -574,7 +634,7 @@ function compute_model(nodes::AbstractVector{Int64}, number_of_neighbors = Data_Manager.get_field("Number of Neighbors") omega = Data_Manager.get_field("Influence Function") bond_damage = Data_Manager.get_field("Bond Damage", "NP1") - C_voigt = Data_Manager.get_field("Elasticity Matrix") + C_voigt = Data_Manager.get_field("Material Gradient") zStiff = include_zero_energy ? Data_Manager.get_field("Zero Energy Stiffness") : nothing diff --git a/src/Models/Material/Material_Models/Zero_Energy_Control/Global_Zero_Energy_Control.jl b/src/Models/Material/Material_Models/Zero_Energy_Control/Global_Zero_Energy_Control.jl index 57b62c8ce..f2b85b73c 100644 --- a/src/Models/Material/Material_Models/Zero_Energy_Control/Global_Zero_Energy_Control.jl +++ b/src/Models/Material/Material_Models/Zero_Energy_Control/Global_Zero_Energy_Control.jl @@ -31,10 +31,10 @@ function init_model(nodes::AbstractVector{Int64}, material_parameter::Dict) Data_Manager.create_constant_node_tensor_field("Zero Energy Stiffness", Float64, dof) - if "Elasticity Matrix" in Data_Manager.get_all_field_keys() + if "Material Gradient" in Data_Manager.get_all_field_keys() return end - hooke_matrix::NodeTensorField{Float64} = Data_Manager.create_constant_node_tensor_field("Elasticity Matrix", + hooke_matrix::NodeTensorField{Float64} = Data_Manager.create_constant_node_tensor_field("Material Gradient", Float64, Int64((dof * (dof + @@ -79,7 +79,7 @@ function compute_control(nodes::AbstractVector{Int64}, "NP1") Kinv::NodeTensorField{Float64} = Data_Manager.get_field("Inverse Shape Tensor") - hooke_matrix::NodeTensorField{Float64} = Data_Manager.get_field("Elasticity Matrix") + hooke_matrix::NodeTensorField{Float64} = Data_Manager.get_field("Material Gradient") zStiff::NodeTensorField{Float64} = Data_Manager.get_field("Zero Energy Stiffness") rotation::Bool = Data_Manager.get_rotation() diff --git a/src/Models/Model_Factory.jl b/src/Models/Model_Factory.jl index 79f126911..0dfbb25b5 100644 --- a/src/Models/Model_Factory.jl +++ b/src/Models/Model_Factory.jl @@ -205,7 +205,7 @@ function compute_models(block_nodes::Dict{Int64,Vector{Int64}}, end end - # Why not update_list.=false? -> avoid neighbors + # Why not update_list.=false? -> avoid neighbors in MPI update_list = Data_Manager.get_field("Update") for (block, nodes) in pairs(block_nodes) update_list[nodes] .= false diff --git a/src/Support/Geometry.jl b/src/Support/Geometry.jl index 24b1b6a2a..0f7d90672 100644 --- a/src/Support/Geometry.jl +++ b/src/Support/Geometry.jl @@ -382,6 +382,18 @@ function compute_strain!(nodes::AbstractVector{Int64}, end end +function compute_linear_strain!(nodes::AbstractVector{Int64}, + deformation_gradient::NodeTensorField{Float64}, + strain::NodeTensorField{Float64}) + for iID in nodes + @inbounds for i in axes(strain, 2), j in axes(strain, 3) + strain[iID, i, j] = 0.5 * (deformation_gradient[iID, i, j] + + deformation_gradient[iID, j, i]) - + (i == j ? 1.0 : 0.0) + end + end +end + """ function rotation_tensor(angles::Vector{Float64}) diff --git a/test/fullscale_tests/test_3D_aniso_material/Reference/3D_anisomat.e b/test/fullscale_tests/test_3D_aniso_material/Reference/3D_anisomat.e index 93847ce04..ad3a1f34d 100644 Binary files a/test/fullscale_tests/test_3D_aniso_material/Reference/3D_anisomat.e and b/test/fullscale_tests/test_3D_aniso_material/Reference/3D_anisomat.e differ diff --git a/test/fullscale_tests/test_3D_aniso_material/Reference/3D_transverse_iso.e b/test/fullscale_tests/test_3D_aniso_material/Reference/3D_transverse_iso.e index 4f6ebfc1d..ed20b251f 100644 Binary files a/test/fullscale_tests/test_3D_aniso_material/Reference/3D_transverse_iso.e and b/test/fullscale_tests/test_3D_aniso_material/Reference/3D_transverse_iso.e differ diff --git a/test/fullscale_tests/test_DCB/Reference/DCBmodel_UMAT.e b/test/fullscale_tests/test_DCB/Reference/DCBmodel_UMAT.e index 046743bce..a72b93271 100644 Binary files a/test/fullscale_tests/test_DCB/Reference/DCBmodel_UMAT.e and b/test/fullscale_tests/test_DCB/Reference/DCBmodel_UMAT.e differ diff --git a/test/fullscale_tests/test_DCB/Reference/DCBmodel_correspondence.e b/test/fullscale_tests/test_DCB/Reference/DCBmodel_correspondence.e index 000b37288..00749ee3e 100644 Binary files a/test/fullscale_tests/test_DCB/Reference/DCBmodel_correspondence.e and b/test/fullscale_tests/test_DCB/Reference/DCBmodel_correspondence.e differ diff --git a/test/fullscale_tests/test_DCB/Reference/DCBmodel_correspondence_bond_associated.e b/test/fullscale_tests/test_DCB/Reference/DCBmodel_correspondence_bond_associated.e index a8ef0529b..990644455 100644 Binary files a/test/fullscale_tests/test_DCB/Reference/DCBmodel_correspondence_bond_associated.e and b/test/fullscale_tests/test_DCB/Reference/DCBmodel_correspondence_bond_associated.e differ diff --git a/test/fullscale_tests/test_DCB/Reference/DCBmodel_correspondence_surface_correction.e b/test/fullscale_tests/test_DCB/Reference/DCBmodel_correspondence_surface_correction.e index 17382ad69..78e20f456 100644 Binary files a/test/fullscale_tests/test_DCB/Reference/DCBmodel_correspondence_surface_correction.e and b/test/fullscale_tests/test_DCB/Reference/DCBmodel_correspondence_surface_correction.e differ diff --git a/test/fullscale_tests/test_correspondence_elastic/Reference/correspondence_strain_pstrain_xy.e b/test/fullscale_tests/test_correspondence_elastic/Reference/correspondence_strain_pstrain_xy.e index 30122d798..43ce4d3d7 100644 Binary files a/test/fullscale_tests/test_correspondence_elastic/Reference/correspondence_strain_pstrain_xy.e and b/test/fullscale_tests/test_correspondence_elastic/Reference/correspondence_strain_pstrain_xy.e differ diff --git a/test/fullscale_tests/test_correspondence_elastic/Reference/correspondence_strain_pstress_xx.e b/test/fullscale_tests/test_correspondence_elastic/Reference/correspondence_strain_pstress_xx.e index 30c116dc7..9ee5823b1 100644 Binary files a/test/fullscale_tests/test_correspondence_elastic/Reference/correspondence_strain_pstress_xx.e and b/test/fullscale_tests/test_correspondence_elastic/Reference/correspondence_strain_pstress_xx.e differ diff --git a/test/fullscale_tests/test_correspondence_elastic/Reference/correspondence_strain_pstress_xy.e b/test/fullscale_tests/test_correspondence_elastic/Reference/correspondence_strain_pstress_xy.e index 2c5643c55..8dab9ce0b 100644 Binary files a/test/fullscale_tests/test_correspondence_elastic/Reference/correspondence_strain_pstress_xy.e and b/test/fullscale_tests/test_correspondence_elastic/Reference/correspondence_strain_pstress_xy.e differ diff --git a/test/fullscale_tests/test_correspondence_elastic_3D/Reference/strain_xy.e b/test/fullscale_tests/test_correspondence_elastic_3D/Reference/strain_xy.e index 7b3611418..4de294489 100644 Binary files a/test/fullscale_tests/test_correspondence_elastic_3D/Reference/strain_xy.e and b/test/fullscale_tests/test_correspondence_elastic_3D/Reference/strain_xy.e differ diff --git a/test/fullscale_tests/test_correspondence_elastic_3D/Reference/strain_xy_angles.e b/test/fullscale_tests/test_correspondence_elastic_3D/Reference/strain_xy_angles.e index 66d2a0fff..66a27ecde 100644 Binary files a/test/fullscale_tests/test_correspondence_elastic_3D/Reference/strain_xy_angles.e and b/test/fullscale_tests/test_correspondence_elastic_3D/Reference/strain_xy_angles.e differ diff --git a/test/fullscale_tests/test_correspondence_elastic_with_zero_E_control/Reference/correspondence_strain_pstrain_zc_xy.e b/test/fullscale_tests/test_correspondence_elastic_with_zero_E_control/Reference/correspondence_strain_pstrain_zc_xy.e index 6f12103dd..f50bbbedc 100644 Binary files a/test/fullscale_tests/test_correspondence_elastic_with_zero_E_control/Reference/correspondence_strain_pstrain_zc_xy.e and b/test/fullscale_tests/test_correspondence_elastic_with_zero_E_control/Reference/correspondence_strain_pstrain_zc_xy.e differ diff --git a/test/fullscale_tests/test_correspondence_elastic_with_zero_E_control/Reference/correspondence_strain_pstress_zc_xy.e b/test/fullscale_tests/test_correspondence_elastic_with_zero_E_control/Reference/correspondence_strain_pstress_zc_xy.e index b5184e391..31ab3b212 100644 Binary files a/test/fullscale_tests/test_correspondence_elastic_with_zero_E_control/Reference/correspondence_strain_pstress_zc_xy.e and b/test/fullscale_tests/test_correspondence_elastic_with_zero_E_control/Reference/correspondence_strain_pstress_zc_xy.e differ diff --git a/test/fullscale_tests/test_large_model_matrix_based/Reference/large_model_matrix_based.e b/test/fullscale_tests/test_large_model_matrix_based/Reference/large_model_matrix_based.e index 046885b1f..35fe71482 100644 Binary files a/test/fullscale_tests/test_large_model_matrix_based/Reference/large_model_matrix_based.e and b/test/fullscale_tests/test_large_model_matrix_based/Reference/large_model_matrix_based.e differ diff --git a/test/fullscale_tests/test_linear_static_matrix_based_solver/Reference/linear_static_matrix_based_bending.e b/test/fullscale_tests/test_linear_static_matrix_based_solver/Reference/linear_static_matrix_based_bending.e index abcb6c951..c191ca4fd 100644 Binary files a/test/fullscale_tests/test_linear_static_matrix_based_solver/Reference/linear_static_matrix_based_bending.e and b/test/fullscale_tests/test_linear_static_matrix_based_solver/Reference/linear_static_matrix_based_bending.e differ diff --git a/test/fullscale_tests/test_linear_static_matrix_based_solver/Reference/linear_static_matrix_based_shear.e b/test/fullscale_tests/test_linear_static_matrix_based_solver/Reference/linear_static_matrix_based_shear.e index e28ef57e8..4a4e3e756 100644 Binary files a/test/fullscale_tests/test_linear_static_matrix_based_solver/Reference/linear_static_matrix_based_shear.e and b/test/fullscale_tests/test_linear_static_matrix_based_solver/Reference/linear_static_matrix_based_shear.e differ diff --git a/test/fullscale_tests/test_linear_static_matrix_based_solver/Reference/linear_static_matrix_based_solver_2D.e b/test/fullscale_tests/test_linear_static_matrix_based_solver/Reference/linear_static_matrix_based_solver_2D.e index 6307349ad..08a6c4e4c 100644 Binary files a/test/fullscale_tests/test_linear_static_matrix_based_solver/Reference/linear_static_matrix_based_solver_2D.e and b/test/fullscale_tests/test_linear_static_matrix_based_solver/Reference/linear_static_matrix_based_solver_2D.e differ diff --git a/test/fullscale_tests/test_linear_static_matrix_based_solver/Reference/linear_static_matrix_based_solver_DCBmodel.e b/test/fullscale_tests/test_linear_static_matrix_based_solver/Reference/linear_static_matrix_based_solver_DCBmodel.e index 343dc89d0..e4b3d39d5 100644 Binary files a/test/fullscale_tests/test_linear_static_matrix_based_solver/Reference/linear_static_matrix_based_solver_DCBmodel.e and b/test/fullscale_tests/test_linear_static_matrix_based_solver/Reference/linear_static_matrix_based_solver_DCBmodel.e differ diff --git a/test/fullscale_tests/test_linear_static_matrix_based_solver/Reference/linear_static_matrix_based_solver_switch_DCBmodel.e b/test/fullscale_tests/test_linear_static_matrix_based_solver/Reference/linear_static_matrix_based_solver_switch_DCBmodel.e index b767911aa..d549ebb6c 100644 Binary files a/test/fullscale_tests/test_linear_static_matrix_based_solver/Reference/linear_static_matrix_based_solver_switch_DCBmodel.e and b/test/fullscale_tests/test_linear_static_matrix_based_solver/Reference/linear_static_matrix_based_solver_switch_DCBmodel.e differ diff --git a/test/fullscale_tests/test_linear_static_matrix_based_solver/Reference/linear_static_matrix_based_tension.e b/test/fullscale_tests/test_linear_static_matrix_based_solver/Reference/linear_static_matrix_based_tension.e index 879ad8977..0ed7aee7a 100644 Binary files a/test/fullscale_tests/test_linear_static_matrix_based_solver/Reference/linear_static_matrix_based_tension.e and b/test/fullscale_tests/test_linear_static_matrix_based_solver/Reference/linear_static_matrix_based_tension.e differ diff --git a/test/fullscale_tests/test_linear_static_matrix_based_solver/Reference/linear_static_matrix_based_thermal_expansion.e b/test/fullscale_tests/test_linear_static_matrix_based_solver/Reference/linear_static_matrix_based_thermal_expansion.e index d5b1661d3..9e8b4c1d8 100644 Binary files a/test/fullscale_tests/test_linear_static_matrix_based_solver/Reference/linear_static_matrix_based_thermal_expansion.e and b/test/fullscale_tests/test_linear_static_matrix_based_solver/Reference/linear_static_matrix_based_thermal_expansion.e differ diff --git a/test/fullscale_tests/test_model_reduction_Verlet_matrix/Reference/verlet_full_matrix.e b/test/fullscale_tests/test_model_reduction_Verlet_matrix/Reference/verlet_full_matrix.e index 1d1c6ae23..5fdf979a6 100644 Binary files a/test/fullscale_tests/test_model_reduction_Verlet_matrix/Reference/verlet_full_matrix.e and b/test/fullscale_tests/test_model_reduction_Verlet_matrix/Reference/verlet_full_matrix.e differ diff --git a/test/fullscale_tests/test_model_reduction_Verlet_matrix/Reference/verlet_reduced.e b/test/fullscale_tests/test_model_reduction_Verlet_matrix/Reference/verlet_reduced.e index 2e999cff6..beedd8b7c 100644 Binary files a/test/fullscale_tests/test_model_reduction_Verlet_matrix/Reference/verlet_reduced.e and b/test/fullscale_tests/test_model_reduction_Verlet_matrix/Reference/verlet_reduced.e differ diff --git a/test/fullscale_tests/test_model_reduction_Verlet_matrix/Reference/verlet_reduced_3D.e b/test/fullscale_tests/test_model_reduction_Verlet_matrix/Reference/verlet_reduced_3D.e index d34542634..4a01204ff 100644 Binary files a/test/fullscale_tests/test_model_reduction_Verlet_matrix/Reference/verlet_reduced_3D.e and b/test/fullscale_tests/test_model_reduction_Verlet_matrix/Reference/verlet_reduced_3D.e differ diff --git a/test/fullscale_tests/test_model_reduction_Verlet_matrix/verlet_full_matrix.yaml b/test/fullscale_tests/test_model_reduction_Verlet_matrix/verlet_full_matrix.yaml index 1b85cf050..057874292 100644 --- a/test/fullscale_tests/test_model_reduction_Verlet_matrix/verlet_full_matrix.yaml +++ b/test/fullscale_tests/test_model_reduction_Verlet_matrix/verlet_full_matrix.yaml @@ -52,7 +52,7 @@ PeriLab: Type: Text File Outputs: Output1: - Output Frequency: 100 + Output Frequency: 10 Output Filename: verlet_full_matrix Output File Type: Exodus Output Variables: @@ -76,7 +76,7 @@ PeriLab: Solver: Final Time: 0.0003 Initial Time: 0.0 - Number of Steps: 178 + Number of Steps: 1780 Material Models: true Verlet Matrix Based: Safety Factor: 0.001 diff --git a/test/fullscale_tests/test_model_reduction_Verlet_matrix/verlet_reduced.yaml b/test/fullscale_tests/test_model_reduction_Verlet_matrix/verlet_reduced.yaml index 44ef45832..bc06ce9cd 100644 --- a/test/fullscale_tests/test_model_reduction_Verlet_matrix/verlet_reduced.yaml +++ b/test/fullscale_tests/test_model_reduction_Verlet_matrix/verlet_reduced.yaml @@ -52,7 +52,7 @@ PeriLab: Type: Text File Outputs: Output1: - Output Frequency: 100 + Output Frequency: 10 Output Filename: verlet_reduced Output File Type: Exodus Output Variables: diff --git a/test/fullscale_tests/test_model_reduction_Verlet_matrix/verlet_reduced_3D.yaml b/test/fullscale_tests/test_model_reduction_Verlet_matrix/verlet_reduced_3D.yaml index 57d82a66c..47c2fa986 100644 --- a/test/fullscale_tests/test_model_reduction_Verlet_matrix/verlet_reduced_3D.yaml +++ b/test/fullscale_tests/test_model_reduction_Verlet_matrix/verlet_reduced_3D.yaml @@ -52,7 +52,7 @@ PeriLab: Type: Text File Outputs: Output1: - Output Frequency: 100 + Output Frequency: 10 Output Filename: verlet_reduced_3D Output File Type: Exodus Output Variables: diff --git a/test/unit_tests/Core/ut_data_manager.jl b/test/unit_tests/Core/ut_data_manager.jl index 5722c0365..64255d1e1 100644 --- a/test/unit_tests/Core/ut_data_manager.jl +++ b/test/unit_tests/Core/ut_data_manager.jl @@ -156,6 +156,23 @@ testfield_keys = PeriLab.Data_Manager.get_all_field_keys() @test "IN" in testfield_keys @test "INP1" in testfield_keys end +@testset "ut_set_fem" begin + @test PeriLab.Data_Manager.data["NP1_to_N"]["B"].N == "BN" + @test PeriLab.Data_Manager.data["NP1_to_N"]["B"].NP1 == "BNP1" + PeriLab.Data_Manager.set_NP1_to_N("B", Bool) + @test PeriLab.Data_Manager.data["NP1_to_N"]["B"].N == "BN" + @test PeriLab.Data_Manager.data["NP1_to_N"]["B"].NP1 == "BNP1" + + @test !haskey(PeriLab.Data_Manager.data["NP1_to_N"], "test_set_NP1_to_N") + + PeriLab.Data_Manager.set_NP1_to_N("test_set_NP1_to_N", Int64) + + @test haskey(PeriLab.Data_Manager.data["NP1_to_N"], "test_set_NP1_to_N") + @test PeriLab.Data_Manager.data["NP1_to_N"]["test_set_NP1_to_N"].N == + "test_set_NP1_to_NN" + @test PeriLab.Data_Manager.data["NP1_to_N"]["test_set_NP1_to_N"].NP1 == + "test_set_NP1_to_NNP1" +end @testset "ut_set_fem" begin @test PeriLab.Data_Manager.fem_active() == false PeriLab.Data_Manager.set_fem(true) @@ -376,8 +393,11 @@ end bdn, bdnp1 = PeriLab.Data_Manager.create_bond_scalar_state("Bond Damage", Float64; default_value = 1) -PeriLab.Data_Manager.create_constant_node_scalar_field("Active", Bool; default_value = true) + @testset "switch_NP1_to_N" begin + PeriLab.Data_Manager.create_constant_node_scalar_field("Active", Bool; + default_value = true) + bmatrixN, bmatrixNP1 = PeriLab.Data_Manager.create_bond_tensor_state("Bmat", Float64, 2) nmatrixN, diff --git a/test/unit_tests/FEM/Element_formulation/ut_lagrange_element.jl b/test/unit_tests/FEM/Element_formulation/ut_lagrange_element.jl index ca3945c2c..2f8313c26 100644 --- a/test/unit_tests/FEM/Element_formulation/ut_lagrange_element.jl +++ b/test/unit_tests/FEM/Element_formulation/ut_lagrange_element.jl @@ -193,41 +193,39 @@ end -0.23018790325073893, 0.04924455046623181 ] - @test PeriLab.Solver_Manager.FEM.Coupling.Arlequin_Coupling.Lagrange_element.get_recursive_lagrange_shape_functions(xi[1, - :], - integration_points[2, - 1], - p) == - [ - 0.0033737364327725374, - 1.0048858548256456, - -0.009921353572324671, - 0.0016617623139063968 - ] - @test PeriLab.Solver_Manager.FEM.Coupling.Arlequin_Coupling.Lagrange_element.get_recursive_lagrange_shape_functions(xi[1, - :], - integration_points[3, - 1], - p) == - [ - 0.0016617623139064258, - -0.009921353572324838, - 1.0048858548256463, - 0.003373736432772594 - ] - @test PeriLab.Solver_Manager.FEM.Coupling.Arlequin_Coupling.Lagrange_element.get_recursive_lagrange_shape_functions(xi[1, - :], - integration_points[4, - 1], - p) == - [ - 0.04924455046623184, - -0.23018790325073904, - 0.5209376877117036, - 0.6600056650728034 - ] + @test isapprox(PeriLab.Solver_Manager.FEM.Coupling.Arlequin_Coupling.Lagrange_element.get_recursive_lagrange_shape_functions(xi[1, + :], + integration_points[2, + 1], + p), + [0.0033737364327725374, + 1.0048858548256456, + -0.009921353572324671, + 0.0016617623139063968 + ]) + @test isapprox(PeriLab.Solver_Manager.FEM.Coupling.Arlequin_Coupling.Lagrange_element.get_recursive_lagrange_shape_functions(xi[1, + :], + integration_points[3, + 1], + p), + [ + 0.0016617623139064258, + -0.009921353572324838, + 1.0048858548256463, + 0.003373736432772594 + ]) + @test isapprox(PeriLab.Solver_Manager.FEM.Coupling.Arlequin_Coupling.Lagrange_element.get_recursive_lagrange_shape_functions(xi[1, + :], + integration_points[4, + 1], + p), + [ + 0.04924455046623184, + -0.23018790325073904, + 0.5209376877117036, + 0.6600056650728034 + ]) end - @testset "ut_get_recursive_lagrange_shape_functions_derivative" begin p = 1 xi = PeriLab.Solver_Manager.FEM.Coupling.Arlequin_Coupling.Lagrange_element.define_lagrangian_grid_space(2, @@ -235,29 +233,29 @@ end p, p ]) - @test PeriLab.Solver_Manager.FEM.Coupling.Arlequin_Coupling.Lagrange_element.get_recursive_lagrange_shape_functions_derivative(xi[1, - :], - 0.0, - p) == - [-0.5, 0.5] + @test isapprox(PeriLab.Solver_Manager.FEM.Coupling.Arlequin_Coupling.Lagrange_element.get_recursive_lagrange_shape_functions_derivative(xi[1, + :], + 0.0, + p), + [-0.5, 0.5]) weights, integration_points = PeriLab.Solver_Manager.FEM.FEM_Basis.get_weights_and_integration_points(2, [ 2, 2 ]) - @test PeriLab.Solver_Manager.FEM.Coupling.Arlequin_Coupling.Lagrange_element.get_recursive_lagrange_shape_functions_derivative(xi[1, - :], - integration_points[1, - 1], - p) == - [-0.5, 0.5] - @test PeriLab.Solver_Manager.FEM.Coupling.Arlequin_Coupling.Lagrange_element.get_recursive_lagrange_shape_functions_derivative(xi[1, - :], - integration_points[2, - 1], - p) == - [-0.5, 0.5] + @test isapprox(PeriLab.Solver_Manager.FEM.Coupling.Arlequin_Coupling.Lagrange_element.get_recursive_lagrange_shape_functions_derivative(xi[1, + :], + integration_points[1, + 1], + p), + [-0.5, 0.5]) + @test isapprox(PeriLab.Solver_Manager.FEM.Coupling.Arlequin_Coupling.Lagrange_element.get_recursive_lagrange_shape_functions_derivative(xi[1, + :], + integration_points[2, + 1], + p), + [-0.5, 0.5]) p = 2 weights, integration_points = PeriLab.Solver_Manager.FEM.FEM_Basis.get_weights_and_integration_points(2, @@ -270,24 +268,24 @@ end p, p ]) - @test PeriLab.Solver_Manager.FEM.Coupling.Arlequin_Coupling.Lagrange_element.get_recursive_lagrange_shape_functions_derivative(xi[1, - :], - integration_points[1, - 1], - p) == - [-1.2745966692414834, 1.5491933384829668, -0.2745966692414834] - @test PeriLab.Solver_Manager.FEM.Coupling.Arlequin_Coupling.Lagrange_element.get_recursive_lagrange_shape_functions_derivative(xi[1, - :], - integration_points[2, - 1], - p) == - [-0.5, 0.0, 0.5] - @test PeriLab.Solver_Manager.FEM.Coupling.Arlequin_Coupling.Lagrange_element.get_recursive_lagrange_shape_functions_derivative(xi[1, - :], - integration_points[3, - 1], - p) == - [0.2745966692414834, -1.5491933384829668, 1.2745966692414834] + @test isapprox(PeriLab.Solver_Manager.FEM.Coupling.Arlequin_Coupling.Lagrange_element.get_recursive_lagrange_shape_functions_derivative(xi[1, + :], + integration_points[1, + 1], + p), + [-1.2745966692414834, 1.5491933384829668, -0.2745966692414834]) + @test isapprox(PeriLab.Solver_Manager.FEM.Coupling.Arlequin_Coupling.Lagrange_element.get_recursive_lagrange_shape_functions_derivative(xi[1, + :], + integration_points[2, + 1], + p), + [-0.5, 0.0, 0.5]) + @test isapprox(PeriLab.Solver_Manager.FEM.Coupling.Arlequin_Coupling.Lagrange_element.get_recursive_lagrange_shape_functions_derivative(xi[1, + :], + integration_points[3, + 1], + p), + [0.2745966692414834, -1.5491933384829668, 1.2745966692414834]) p = 3 weights, integration_points = PeriLab.Solver_Manager.FEM.FEM_Basis.get_weights_and_integration_points(2, @@ -300,28 +298,48 @@ end p, p ]) - @test PeriLab.Solver_Manager.FEM.Coupling.Arlequin_Coupling.Lagrange_element.get_recursive_lagrange_shape_functions_derivative(xi[1, - :], - integration_points[1, - 1], - p) == - [-2.157653673851862, 3.035404320468968, -1.0978476193823496, 0.22009697276524381] - @test PeriLab.Solver_Manager.FEM.Coupling.Arlequin_Coupling.Lagrange_element.get_recursive_lagrange_shape_functions_derivative(xi[1, - :], - integration_points[2, - 1], - p) == - [-0.5150319221529817, -0.7198615816069815, 1.484818929672908, -0.2499254259129448] - @test PeriLab.Solver_Manager.FEM.Coupling.Arlequin_Coupling.Lagrange_element.get_recursive_lagrange_shape_functions_derivative(xi[1, - :], - integration_points[3, - 1], - p) == - [0.249925425912945, -1.4848189296729082, 0.7198615816069811, 0.5150319221529819] - @test PeriLab.Solver_Manager.FEM.Coupling.Arlequin_Coupling.Lagrange_element.get_recursive_lagrange_shape_functions_derivative(xi[1, - :], - integration_points[4, - 1], - p) == - [-0.22009697276524398, 1.09784761938235, -3.035404320468968, 2.1576536738518617] + @test isapprox(PeriLab.Solver_Manager.FEM.Coupling.Arlequin_Coupling.Lagrange_element.get_recursive_lagrange_shape_functions_derivative(xi[1, + :], + integration_points[1, + 1], + p), + [ + -2.157653673851862, + 3.035404320468968, + -1.0978476193823496, + 0.22009697276524381 + ]) + @test isapprox(PeriLab.Solver_Manager.FEM.Coupling.Arlequin_Coupling.Lagrange_element.get_recursive_lagrange_shape_functions_derivative(xi[1, + :], + integration_points[2, + 1], + p), + [ + -0.5150319221529817, + -0.7198615816069815, + 1.484818929672908, + -0.2499254259129448 + ]) + @test isapprox(PeriLab.Solver_Manager.FEM.Coupling.Arlequin_Coupling.Lagrange_element.get_recursive_lagrange_shape_functions_derivative(xi[1, + :], + integration_points[3, + 1], + p), + [ + 0.249925425912945, + -1.4848189296729082, + 0.7198615816069811, + 0.5150319221529819 + ]) + @test isapprox(PeriLab.Solver_Manager.FEM.Coupling.Arlequin_Coupling.Lagrange_element.get_recursive_lagrange_shape_functions_derivative(xi[1, + :], + integration_points[4, + 1], + p), + [ + -0.22009697276524398, + 1.09784761938235, + -3.035404320468968, + 2.1576536738518617 + ]) end diff --git a/test/unit_tests/FEM/ut_FEM_routines.jl b/test/unit_tests/FEM/ut_FEM_routines.jl index 12631a8c2..0185ac330 100644 --- a/test/unit_tests/FEM/ut_FEM_routines.jl +++ b/test/unit_tests/FEM/ut_FEM_routines.jl @@ -495,16 +495,24 @@ end [2, 2]) == ([1.0 1.0; 1.0 1.0], [-0.5773502691896258 -0.5773502691896258; 0.5773502691896258 0.5773502691896258]) - @test PeriLab.Solver_Manager.FEM.FEM_Basis.get_weights_and_integration_points(3, - [2, 3, 4]) == - ([1.0 0.5555555555555556 0.34785484513745385 - 1.0 0.8888888888888888 0.6521451548625462 - 0.0 0.5555555555555556 0.6521451548625462 - 0.0 0.0 0.34785484513745385], - [-0.5773502691896258 -0.7745966692414834 -0.8611363115940526 - 0.5773502691896258 0.0 -0.3399810435848563 - 0.0 0.7745966692414834 0.3399810435848563 - 0.0 0.0 0.8611363115940526]) + testval = PeriLab.Solver_Manager.FEM.FEM_Basis.get_weights_and_integration_points(3, + [ + 2, + 3, + 4 + ]) + + @test isapprox(testval[1], + [1.0 0.5555555555555556 0.34785484513745385 + 1.0 0.8888888888888888 0.6521451548625462 + 0.0 0.5555555555555556 0.6521451548625462 + 0.0 0.0 0.34785484513745385]) + @test isapprox(testval[2], + [-0.5773502691896258 -0.7745966692414834 -0.8611363115940526 + 0.5773502691896258 0.0 -0.3399810435848563 + 0.0 0.7745966692414834 0.3399810435848563 + 0.0 0.0 0.8611363115940526]) + @test PeriLab.Solver_Manager.FEM.FEM_Basis.get_weights_and_integration_points(3, [2, 1, 1]) == ([1.0 2.0 2.0; 1.0 0.0 0.0], diff --git a/test/unit_tests/Models/Material/Material_Models/Correspondence/ut_Correspondence_UMAT.jl b/test/unit_tests/Models/Material/Material_Models/Correspondence/ut_Correspondence_UMAT.jl index 3dd488a57..d0258495f 100644 --- a/test/unit_tests/Models/Material/Material_Models/Correspondence/ut_Correspondence_UMAT.jl +++ b/test/unit_tests/Models/Material/Material_Models/Correspondence/ut_Correspondence_UMAT.jl @@ -22,72 +22,85 @@ end file = "../src/Models/Material/UMATs/libperuser.so" end directory = PeriLab.Data_Manager.get_directory() - @test !isnothing(PeriLab.Solver_Manager.Model_Factory.Material.Correspondence.Correspondence_UMAT.init_model(Vector{Int64}(1:nodes), - Dict{String, - Any}("File" => file, - "Number of Properties" => 3, - "Property_1" => 2, - "Property_2" => 2, - "Property_3" => 2.4, - "Property_4" => 2))) + + # Material properties + E = 2.0 + nu = 0.1 + G = E / (2 * (1 + nu)) # Shear modulus + @test_logs (:error, "File $(joinpath(pwd(), directory, file * "_not_there")) does not exist, please check name and directory.") PeriLab.Solver_Manager.Model_Factory.Material.Correspondence.Correspondence_UMAT.init_model(Vector{Int64}(1:nodes), Dict{String, - Any}("File" => file * + Any}("Material Model" => "Correspondence UMAT", + "Poisson's Ratio" => nu, + "Young's Modulus" => E, + "Shear Modulus" => G, + "File" => file * "_not_there", "Number of Properties" => 3)) @test_logs (:error, "Number of Properties must be at least equal 1") PeriLab.Solver_Manager.Model_Factory.Material.Correspondence.Correspondence_UMAT.init_model(Vector{Int64}(1:nodes), Dict{String, - Any}("File" => file)) + Any}("Material Model" => "Correspondence UMAT", + "Poisson's Ratio" => nu, + "Young's Modulus" => E, + "Shear Modulus" => G, + "File" => file)) @test_logs (:error, "UMAT file is not defined.") PeriLab.Solver_Manager.Model_Factory.Material.Correspondence.Correspondence_UMAT.init_model(Vector{Int64}(1:nodes), Dict{String, - Any}()) + Any}("Material Model" => "Correspondence UMAT", + "Poisson's Ratio" => nu, + "Young's Modulus" => E, + "Shear Modulus" => G)) @test_logs (:error, "Due to old Fortran standards only a name length of 80 is supported") PeriLab.Solver_Manager.Model_Factory.Material.Correspondence.Correspondence_UMAT.init_model(Vector{Int64}(1:nodes), Dict{String, - Any}("File" => file, + Any}("Material Model" => "Correspondence UMAT", + "File" => file, "Number of Properties" => 3, "Property_1" => 2, "Property_2" => 2.4, "Property_3" => 2.4, + "Poisson's Ratio" => nu, + "Young's Modulus" => E, + "Shear Modulus" => G, "UMAT Material Name" => "a"^81)) - @test !isnothing(PeriLab.Solver_Manager.Model_Factory.Material.Correspondence.Correspondence_UMAT.init_model(Vector{Int64}(1:nodes), - Dict{String, - Any}("File" => file, - "Number of Properties" => 3, - "Property_1" => 2, - "Property_2" => 2, - "Property_3" => 2.4, - "UMAT Material Name" => "a"^80))) properties = PeriLab.Data_Manager.get_field("Properties") @test length(properties) == 3 @test properties[1] == 2 - @test properties[2] == 2 + @test properties[2] == 2.4 @test properties[3] == 2.4 @test_logs (:error, "Predefined field ''test_field_2'' is not defined in the mesh file.") PeriLab.Solver_Manager.Model_Factory.Material.Correspondence.Correspondence_UMAT.init_model(Vector{Int64}(1:nodes), Dict{String, - Any}("File" => file, + Any}("Material Model" => "Correspondence UMAT", + "File" => file, "Number of Properties" => 3, "Property_1" => 2, "Property_2" => 2, "Property_3" => 2.4, + "Poisson's Ratio" => nu, + "Young's Modulus" => E, + "Shear Modulus" => G, "Predefined Field Names" => "test_field_2 test_field_3")) test_1 = PeriLab.Data_Manager.create_constant_node_scalar_field("test_field_2", Float64) test_1[1] = 7.3 test_2 = PeriLab.Data_Manager.create_constant_node_scalar_field("test_field_3", Float64) test_2 .= 3 - mat_dict = Dict{String,Any}("File" => file, + mat_dict = Dict{String,Any}("Material Model" => "Correspondence UMAT", + "File" => file, "UMAT name" => "test_sub", "Number of Properties" => 3, "Property_1" => 2, "Property_2" => 2, "Property_3" => 2.4, + "Poisson's Ratio" => nu, + "Young's Modulus" => E, + "Shear Modulus" => G, "Predefined Field Names" => "test_field_2 test_field_3") PeriLab.Solver_Manager.Model_Factory.Material.Correspondence.Correspondence_UMAT.init_model(Vector{Int64}(1:nodes), mat_dict) @@ -100,11 +113,15 @@ end @test fields[1, 2] == test_2[1] @test fields[2, 2] == test_2[2] @test mat_dict["UMAT name"] == "test_sub" - mat_dict = Dict{String,Any}("File" => file, + mat_dict = Dict{String,Any}("Material Model" => "Correspondence UMAT", + "File" => file, "Number of Properties" => 3, "Property_1" => 2, "Property_2" => 2, "Property_3" => 2.4, + "Poisson's Ratio" => nu, + "Young's Modulus" => E, + "Shear Modulus" => G, "Predefined Field Names" => "test_field_2 test_field_3") @test !haskey(mat_dict, "UMAT name") PeriLab.Solver_Manager.Model_Factory.Material.Correspondence.Correspondence_UMAT.init_model(Vector{Int64}(1:nodes),