From 6e467691f0ca1faae24b2fb723909f75a80512a0 Mon Sep 17 00:00:00 2001 From: Marja Rapo Date: Wed, 23 Aug 2017 15:28:20 +0300 Subject: [PATCH] Fix documentation Update documentation of several functions to match documentation guide. --- docs/src/figs/mesh.png | Bin 0 -> 6976 bytes src/elements.jl | 14 ++++- src/io.jl | 63 +++++++++++++++++------ src/preprocess.jl | 87 +++++++++++++++++++++++++++++--- src/preprocess_abaqus_reader.jl | 7 +++ src/problems.jl | 80 +++++++++++++++++++++-------- 6 files changed, 207 insertions(+), 44 deletions(-) create mode 100644 docs/src/figs/mesh.png diff --git a/docs/src/figs/mesh.png b/docs/src/figs/mesh.png new file mode 100644 index 0000000000000000000000000000000000000000..b9d7e3cd76ef00afc544fbd66bd9948455f8103b GIT binary patch literal 6976 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 A`2YX_ literal 0 HcmV?d00001 diff --git a/src/elements.jl b/src/elements.jl index 9af660c..4b48e67 100644 --- a/src/elements.jl +++ b/src/elements.jl @@ -9,11 +9,21 @@ type Element{E<:AbstractBasis} properties :: E end -""" Construct a new element of type E. +""" + Element(element_type, connectivity_vector) + +Construct a new element where element_type is the type of the element +and connectivity_vector is the vector of nodes that the element is connected to. Examples -------- -julia> element = Element(Tri3, [1, 2, 3]) +In the example a new element (E in the figure below) of type Tri3 is created. +This spesific element connects to nodes 89, 43, 12 in the finite element mesh. + +```@example +element = Element(Tri3, [89, 43, 12]) +``` +![img](figs/mesh.png) """ function Element{E<:AbstractBasis}(::Type{E}, connectivity::Vector{Int}) return Element{E}(-1, connectivity, [], Dict(), E()) diff --git a/src/io.jl b/src/io.jl index be6022c..9d16f92 100644 --- a/src/io.jl +++ b/src/io.jl @@ -24,12 +24,16 @@ function xmffile(xdmf::Xdmf) return xdmf.name*".xmf" end -""" Initialize a new Xdmf object. """ +""" + Xdmf(name, version="3.0", overwrite=false) + +Initialize a new Xdmf object. +""" function Xdmf(name::String; version="3.0", overwrite=false) xdmf = new_element("Xdmf") h5file = "$name.h5" xmlfile = "$name.xmf" - + if isfile(h5file) if overwrite info("Result file $h5file exists, removing old file.") @@ -38,7 +42,7 @@ function Xdmf(name::String; version="3.0", overwrite=false) error("Result file $h5file exists, use Xdmf($name; overwrite=true) to rewrite results") end end - + if isfile(xmlfile) if overwrite info("Result file $xmlfile exists, removing old file.") @@ -55,7 +59,11 @@ function Xdmf(name::String; version="3.0", overwrite=false) return Xdmf(name, xdmf, hdf, 1, "HDF") end -""" Return the basic structure of Xdmf document. Creates a new TemporalCollection if not found. +""" + get_temporal_collection(xdmf) + +Return the basic structure of Xdmf document. +Creates a new TemporalCollection if not found. Basic structure for XML part of Xdmf file is @@ -79,7 +87,10 @@ function get_temporal_collection(xdmf::Xdmf) return grid end -""" Returns some spesific child xml element from a array of XMLElement based on, +""" + xdmf_filter(child_elements, child_name) + +Returns some spesific child xml element from an array of XMLElement based on, "Xdmf extensions" see [1] for details. Parameters @@ -93,8 +104,8 @@ Returns ------- nothing if nothing is found, otherwise XMLElement matching to filtering -Examples --------- +#Examples + julia> grid1 = new_element("Grid") julia> add_text(grid1, "I am first grid") julia> grid2 = new_element("Grid") @@ -176,8 +187,13 @@ function xdmf_filter(child_elements, child_name) return nothing end -""" Traverse XML path. Xdmf filtering can be used, so it's possible to find -data from xml using syntax e.g. +""" + traverse(xdmf, x, attr_name) + +Traverse XML path. Xdmf filtering can be used, so it's possible to find +data from xml using syntax e.g. + +#Example julia> traverse(xdmf, x, "/Domain/Grid[2]/Grid[@Name=Frame 1]/DataItem") """ @@ -203,12 +219,17 @@ function traverse(xdmf::Xdmf, x::XMLElement, attr_name::String) new_path = join(items[2:end], '/') return traverse(xdmf, new_item, new_path) end - + child = xdmf_filter(childs, attr_name) return child end -""" Read data from Xdmf file. +""" + read(xdmf, path) + +Read data from Xdmf file. + +#Example Traversing is supported, so one can easily traverse XML tree e.g. julia> read(xdmf, "/Domain/Grid/Grid[2]/Geometry") @@ -230,7 +251,11 @@ function read(xdmf::Xdmf, path::String) end end +""" + save!(xdmf) +Save the xdmf file. +""" function save!(xdmf::Xdmf) doc = XMLDocument() set_root(doc, xdmf.xml) @@ -264,7 +289,11 @@ function new_dataitem{T,N}(xdmf::Xdmf, path::String, data::Array{T,N}) return dataitem end -""" Create a new DataItem element, hdf path automatically determined. """ +""" + new_dataitem(xdmf, data) + +Create a new DataItem element, hdf path automatically determined. +""" function new_dataitem{T,N}(xdmf::Xdmf, data::Array{T,N}) if xdmf.format == "XML" # Path can be whatever as XML format does not store to HDF at all @@ -298,10 +327,12 @@ global const xdmf_element_mapping = Dict( "Wedge15" => "Wedge_15", "Hex20" => "Hex_20") -""" Write new fields to Xdmf file. +""" + update_xdmf!(xdmf, problem, time, fields) + +Write new fields to Xdmf file. -Examples --------- +#Example To write displacement and temperature fields from p1 at time t=0.0: @@ -359,7 +390,7 @@ function update_xdmf!(xdmf::Xdmf, problem::Problem, time::Float64, fields::Vecto time_element = new_child(spatial_collection, "Time") set_attribute(time_element, "Value", time) end - + # 3.1 make sure that Grid element we found really is SpatialCollection collection_type = attribute(spatial_collection, "CollectionType"; required=true) @assert collection_type == "Spatial" diff --git a/src/preprocess.jl b/src/preprocess.jl index 89d9ac6..3890374 100644 --- a/src/preprocess.jl +++ b/src/preprocess.jl @@ -34,7 +34,7 @@ end """ Mesh(m::Dict) -Create new `Mesh` using data `m`. It is assumed that `m` is in format what +Create a new `Mesh` using data `m`. It is assumed that `m` is in format what `abaqus_read_mesh` in `AbaqusReader.jl` is returning. """ function Mesh(m::Dict) @@ -56,16 +56,33 @@ function Mesh(m::Dict) return mesh end +""" + add_node!(mesh, nid, ncoords) + +Add node into the mesh. `nid` is node id and `ncoords` are the node +coordinates. +""" function add_node!(mesh::Mesh, nid::Int, ncoords::Vector{Float64}) mesh.nodes[nid] = ncoords end +""" + add_nodes!(mesh, nodes) + +Add nodes into the mesh. +""" function add_nodes!(mesh::Mesh, nodes::Dict{Int, Vector{Float64}}) for (nid, ncoords) in nodes add_node!(mesh, nid, ncoords) end end +""" + add_node_to_node_set!(mesh, nid, ncoords) + +Add nodes into a node set. `set_name` is the name of the set and `nids...` +are all the node id:s that wants to be added. +""" function add_node_to_node_set!(mesh::Mesh, set_name, nids...) if !haskey(mesh.node_sets, set_name) mesh.node_sets[set_name] = Set{Int}() @@ -74,7 +91,12 @@ function add_node_to_node_set!(mesh::Mesh, set_name, nids...) return end -""" Create a new node set from nodes in element set. """ +""" + create_node_set_from_element_set!(mesh, set_names...) + +Create a new node set from the nodes in an element set. ´set_names...´ are all +the set names to be inserted in the function. +""" function create_node_set_from_element_set!(mesh::Mesh, set_names::String...) for set_name in set_names set_name = Symbol(set_name) @@ -88,21 +110,43 @@ function create_node_set_from_element_set!(mesh::Mesh, set_names::String...) return end +""" + create_node_set_from_element_set!(mesh, set_name) + +Create a new node set from an element set. +""" function create_node_set_from_element_set!(mesh::Mesh, set_name::Symbol) create_node_set_from_element_set!(mesh, string(set_name)) end +""" + add_element!(mesh, elid, eltype, connectivity) + +Add an element into the mesh. ´elid´ is the element id, ´eltype´ is the type of +the element and ´connectivity´ is the connectivity of the element. +""" function add_element!(mesh::Mesh, elid::Int, eltype::Symbol, connectivity::Vector{Int}) mesh.elements[elid] = connectivity mesh.element_types[elid] = eltype end +""" + add_elements!(mesh, elements) + +Add elements into the mesh. +""" function add_elements!(mesh::Mesh, elements::Dict{Int, Tuple{Symbol, Vector{Int}}}) for (elid, (eltype, elcon)) in elements add_element!(mesh, elid, eltype, elcon) end end +""" + add_element_to_element_set!(mesh, set_name, elids...) + +Add elements into the mesh. ´set_name´ is the name of the element set and +´elids..´ are id:s of all the elements that wants to be added. +""" function add_element_to_element_set!(mesh::Mesh, set_name, elids...) if !haskey(mesh.element_sets, set_name) mesh.element_sets[set_name] = Set{Int}() @@ -110,6 +154,11 @@ function add_element_to_element_set!(mesh::Mesh, set_name, elids...) push!(mesh.element_sets[set_name], elids...) end +""" + copy(mesh) + +Copy the mesh. +""" function copy(mesh::Mesh) mesh2 = Mesh() mesh2.nodes = copy(mesh.nodes) @@ -120,6 +169,11 @@ function copy(mesh::Mesh) return mesh2 end +""" + filter_by_element_id(mesh, element_ids) + +Filter elements by their id's. +""" function filter_by_element_id(mesh::Mesh, element_ids::Vector{Int}) mesh2 = copy(mesh) mesh2.elements = Dict() @@ -131,10 +185,20 @@ function filter_by_element_id(mesh::Mesh, element_ids::Vector{Int}) return mesh2 end +""" + filter_by_element_set(mesh, set_name) + +Filter elements by an element set. +""" function filter_by_element_set(mesh::Mesh, set_name) filter_by_element_id(mesh::Mesh, collect(mesh.element_sets[set_name])) end +""" + create_element(mesh, id) + +Create an element from the mesh by it's id. +""" function create_element(mesh::Mesh, id::Int) connectivity = mesh.elements[id] element_type = getfield(JuliaFEM, mesh.element_types[id]) @@ -144,6 +208,11 @@ function create_element(mesh::Mesh, id::Int) return element end +""" + create_elements(mesh, element_type=nothing) + +Create elements from the mesh filtered by their type. +""" function create_elements(mesh::Mesh; element_type=nothing) element_ids = collect(keys(mesh.elements)) if element_type != nothing @@ -177,7 +246,11 @@ function create_elements(mesh::Mesh, element_sets::AbstractString...; element_ty end -""" find npts nearest nodes from mesh and return id numbers as list. """ +""" + find_nearest_nodes(mesh, coords, npts=1; node_set=nothing) + +find npts nearest nodes from the mesh and return their id numbers as a list. +""" function find_nearest_nodes(mesh::Mesh, coords::Vector{Float64}, npts::Int=1; node_set=nothing) dist = Dict{Int, Float64}() for (nid, c) in mesh.nodes @@ -197,9 +270,11 @@ function find_nearest_node(mesh::Mesh, coords::Vector{Float64}; node_set=nothing end """ -Apply new node ordering to elements. In JuliaFEM same node ordering is used -than in ABAQUS and if mesh is parsed from FEM format with other node ordering -this can be used to reorder nodes. + reorder_element_connectivity!(mesh, mapping) + +Apply a new node ordering to elements. JuliaFEM uses the same node ordering as +ABAQUS. If the mesh is parsed from FEM format with some other node ordering, +this function can be used to reorder the nodes. Parameters ---------- diff --git a/src/preprocess_abaqus_reader.jl b/src/preprocess_abaqus_reader.jl index 8c114ba..0fb0ba0 100644 --- a/src/preprocess_abaqus_reader.jl +++ b/src/preprocess_abaqus_reader.jl @@ -3,6 +3,13 @@ using AbaqusReader +""" + abaqus_read_mesh(fn::String) + +Read and parse ABAQUS `.inp` file. + +`fn` (filename) is the name of the file to parse. +""" function abaqus_read_mesh(fn::String) m = AbaqusReader.abaqus_read_mesh(fn) return Mesh(m) diff --git a/src/problems.jl b/src/problems.jl index 3bfce2c..cd26991 100644 --- a/src/problems.jl +++ b/src/problems.jl @@ -8,7 +8,7 @@ abstract type MixedProblem<:AbstractProblem end """ General linearized problem to solve - (K₁+K₂)Δu + C1*Δλ = f₁+f₂ + (K₁+K₂)Δu + C1'*Δλ = f₁+f₂ C2Δu + D*Δλ = g """ type Assembly @@ -81,37 +81,59 @@ function isempty(assembly::Assembly) return T end +""" +Defines types for Problem variables. + +# Examples + +The type of 'elements' is Vector{Element} + +Add elements into the Problem element list. +```@example +a = [1, 2, 3] +Problem.elements = a +``` + +""" type Problem{P<:AbstractProblem} - name :: AbstractString # descriptive name for problem + name :: AbstractString # descriptive name for the problem dimension :: Int # degrees of freedom per node - parent_field_name :: AbstractString # (optional) name of parent field e.g. "displacement" + parent_field_name :: AbstractString # (optional) name of the parent field e.g. "displacement" elements :: Vector{Element} - dofmap :: Dict{Element, Vector{Int64}} # connects element local dofs to global dofs + dofmap :: Dict{Element, Vector{Int64}} # connects the element local dofs to the global dofs assembly :: Assembly fields :: Dict{AbstractString, Field} postprocess_fields :: Vector{String} properties :: P end -""" Construct a new field problem. +""" + Problem(problem_type, problem_name::String, problem_dimension) -Examples --------- -Create vector-valued (dim=3) elasticity problem: +Construct a new field problem where `problem_type` is the type of the problem +(Elasticity, Dirichlet, etc.), `problem_name` is the name of the problem and +`problem_dimension` is the number of DOF:s in one node (2 in a 2D problem, 3 +in an elastic 3D problem, 6 in a 3D beam problem, etc.). -julia> prob1 = Problem(Elasticity, "this is my problem", 3) -julia> prob2 = Problem(Elasticity, 3) +# Examples + +Create a vector-valued (dim=3) elasticity problem: + +```@example +prob1 = Problem(Elasticity, "this is my problem", 3) +``` """ function Problem{P<:FieldProblem}(::Type{P}, name::AbstractString, dimension::Int64) return Problem{P}(name, dimension, "none", [], Dict(), Assembly(), Dict(), Vector(), P()) end -""" Construct a new boundary problem. +""" +Construct a new boundary problem. Examples -------- -Create Dirichlet boundary problem for vector-valued (dim=3) elasticity problem. +Create a Dirichlet boundary problem for a vector-valued (dim=3) elasticity problem. julia> bc1 = Problem(Dirichlet, "support", 3, "displacement") solver. @@ -150,7 +172,14 @@ function update!{P<:AbstractProblem}(problem::P, attr::Pair{String, String}...) end end -""" Initialize element ready for calculation. """ +""" + function initialize!(problem_type, element_name, time) + +Initialize the element ready for calculation, where `problem_type` is the type +of the problem (Elasticity, Dirichlet, etc.), `element_name` is the name of a +constructed element (see Element(element_type, connectivity_vector)) and `time` +is the starting time of the initializing process. +""" function initialize!(problem::Problem, element::Element, time::Float64) field_name = get_unknown_field_name(problem) field_dim = get_unknown_field_dimension(problem) @@ -165,7 +194,7 @@ function initialize!(problem::Problem, element::Element, time::Float64) end end - # if boundary problem, initialize field for main problem too + # if a boundary problem, initialize also a field for the main problem is_boundary_problem(problem) || return field_name = get_parent_field_name(problem) if !haskey(element, field_name) @@ -183,7 +212,11 @@ function initialize!(problem::Problem, time::Float64=0.0) end end -""" Update problem solution vector for assembly. """ +""" + update!(problem, assembly, u, la) + +Update the problem solution vector for assembly. +""" function update!(problem::Problem, assembly::Assembly, u::Vector, la::Vector) # resize & fill with zeros vectors if length mismatch with current solution @@ -227,13 +260,16 @@ function update!(problem::Problem, assembly::Assembly, u::Vector, la::Vector) return assembly.u, assembly.la end -""" Return global solution (u, la) for problem. +""" + get_global_solution(problem, assembly) + +Return a global solution (u, la) for a problem. Notes ----- -If length of solution vector != number of nodes, i.e. field dimension is -something other than 1, reshape vectors so it's length matches to the -number of nodes so that one can easily get nodal results. +If the length of solution vector != number of nodes, i.e. the field dimension is +something else than 1, reshape vectors so that their length matches to the +number of nodes. This helps to get nodal results easily. """ function get_global_solution(problem::Problem, assembly::Assembly) u = assembly.u @@ -251,7 +287,11 @@ function get_global_solution(problem::Problem, assembly::Assembly) end end -""" Update solution from assebly to elements. """ +""" + update!(problem, assembly, elements, time) + +Update a solution from the assebly to elements. +""" function update!{P<:FieldProblem}(problem::Problem{P}, assembly::Assembly, elements::Vector{Element}, time::Float64) u, la = get_global_solution(problem, assembly) field_name = get_unknown_field_name(problem)