feutil#

Purpose

Finite element mesh handling utilities.

Syntax

[out,out1] = feutil('CommandString',model,...)

Description

feutil provides a number of tools for mesh creation and manipulation.

Some commands return the model structure whereas some others return only the element matrix. To mesh a complex structure one can mesh each subpart in a different model structure (model, mo1, ...) and combine each part using AddTest command.

To handle complex model combination (not only meshes but whole models with materials, bases, ...), one can use the CombineModel command.

Available feutil commands are

Advanced#

Advanced command with non trivial input/output formats or detailed options are listed under feutila.

AddElt#

model.Elt=feutil('AddElt',model.Elt,'EltName',data)

This command can be used to add new elements to a model. EltName gives the element name used to fill the header. data describes elements to add (one row per element).

Command option -newId forces new EltId following the maximum EltId of model.Elt to be assigned to the added elements, using this command generates a second output providing the EltId convertion list [oldId newId;...] for the added elements.

Following example adds celas elements to the basis of a simple cube model.

% Adding elements to a model 
femesh('Reset'); model=femesh('Testhexa8'); % simple cube model
data=[1 0 123 0 0 1 1e3; 2 0 123 0 0 1 1e3;
      3 0 123 0 0 1 1e3; 4 0 123 0 0 1 1e3]; % n1 n2 dof1 dof2 EltId ProId k
model.Elt=feutil('AddElt',model.Elt,'celas',data);
cf=feplot(model);

% Cleanup eltid for model [eltid,model.Elt]=feutil('EltIdFix;',model); el1=[1 4 123 0 1 0 1000]; [model.Elt,r1]=feutil('AddElt-newId',model.Elt,'celas',el1);

AddNode[,New] [, From i] [,epsl val]#

[AllNode,ind]=feutil('AddNode',OldNode,NewNode);

Combine (without command option New) or append (with command option New) NewNode to OldNode. Without command option New, AddNode combines NewNode to OldNode: it finds nodes in NewNode that coincide with nodes in OldNode and appends other nodes to form AllNode. With command option New, AddNode simply appends NewNode to OldNode.

AllNode is the new node matrix with added nodes. ind (optional) gives the indices of the NewNode nodes in the AllNode matrix.

NewNode can be specified as a matrix with three columns giving xyz coordinates. The minimal distance below which two nodes are considered identical is given by sdtdef epsl (default 1e-6).

[AllNode,ind]=feutil('AddNode From 10000',OldNode,NewNode); gives node numbers starting at 10000 for nodes in NewNode that are not in OldNode.

SDT uses an optimized algorithm available in feutilb .

By default, nodes that repeated in NewNode are coalesced onto the same node (a single new node is added). If there is not need for that coalescence, you can get faster results with AddNode-nocoal.

ind=feutilb('AddNode -near epsl value',n1,n2); returns a sparse matrix with non zero values in a given colum indicating of n1 nodes that are within epsl of each n2 node (rows/columns correspond to n2/n1 node numbers).

id=feutilb('AddNode -nearest epsl value',n1,xyz); returns vector giving the nearest n1 NodeId to each xyz node the search area being limited to epsl. When specified with a 7 column n2, the result is sparse(n2(:,1),1,n1_index). For fine meshes the algorithm can use a lot of memory. If n2 is not too large it is then preferable to use an AddNode command with a tolerance sufficient for a match [n3,ind]=feutil('AddNode epsl value',n1,n2);id=n3(ind,1).

AddSet[NodeId, EltId, FaceId, EdgeId]#

Command AddSet packages the generation of sets in an SDT model. Depending on the type of set several command options can apply.

  • model=feutil('AddSetNodeId',model,'name','FindNodeString') adds the selection FindNodeString as a set of nodes name to model. FindNodeString can be replaced by a column vector of NodeId.
  • Syntax is the same for AddSetEltId with a FindEltString selection. FindEltString can be replaced by a column vector of EltId. Command option FromInd allows providing element indices instead of IDs.
  • For faces with AddSetFaceId, the element selection argument FindEltString must result in the generation of a face selection. One can use the SelFace token in the FindEltString to this purpose. As an alternative, one can directly provide an element matrix resulting from a SelFace selection, or a 2 column list of respectively EltId and Face identifiers. For face identifier conversion to other code conventions, one can use command option @fun to obtain a set with a ConvFcn set to fun, see set for more details.
  • For generation of EdgeId sets, the element selection argument FindEltString must result in the generation of an edge selection. One can use the SelEdge token in the FindEltString to this purpose. As an alternative, one can directly provide an element matrix resulting from a SelEdge selection, or a 2 column list of respectively EltId and Edge identifiers. Support for edge identifier conversion and setname selection is not provided yet.

The option -id value can be added to the command to specify a set ID.

By default the generated set erases any previously existing set with the same name, regardless of the type. Command option New alters this behavior by incrementing the set name. One can use the command second output to recover the new name.


Command option -Append allows generation of a meta-set. The meta-set is an agglomeration of several sets of possibly various types, see set for more information.

  • The base syntax requires providing the meta-set name and the set name. model=feutil('AddSetEltId -Append',model,'name','FindEltString','subname') will thus add the elements found as a sub set named subname of meta-set name. subname can be a 1x2 cell array {subname,subgroup} providing the set name and the set subgroup it belongs to. By default subgroup is set to the set type.
  • Generation of a meta-set gathering all base sets in the model is possible by omitting subname and the FindEltString.


By default command AddSet returns the model as a first output and possibly the set data structure in a second output. Command option -get alters this behavior returning the data set structure without adding it to the model. For FaceId or EdgeId sets, command option -get can output the elements selected by the FindEltString.

Following example defines a set of each type on the ubeam model:

% Defining node elements or face sets in a model
model=demosdt('demo ubeam'); 
% Add a set of NodeId, and recover set data structure
[model,data]=feutil('AddSetNodeId',model,'nodeset','z==1');
% Add a set of EltId 
model=feutil('AddSetEltId -id18',model,'eltset','WithNode{z==0}');
% Generate a set of EltId without model addition
data=feutil('AddSetEltId -id18 -get',model,'eltset','WithNode{z==0}');
% Generate a set of FaceId
model=feutil('AddSetFaceId',model,'faceset','SelFace & InNode{z==0}');
% Generate a set of FaceId without model addition
[data1,elt]=feutil('AddSetFaceId -get',model,'faceset','SelFace & WithNode{z==0}');

% Sample visalization commands cf=feplot; % get feplot handle [elt,ind]=feutil('FindElt setname eltset',model); % FindElt based on set name cf.sel='setname faceset'; % element selection based on a FaceId set

% Lower level set handling % Generate a FaceSet from an EltSet r1=cf.Stack{'eltset'};r1.type='FaceId';r1.data(:,2)=1; cf.Stack{'set','faceset'}=r1; % Generate a DOF set from a node set r1=cf.Stack{'nodeset'};r1.type='DOF';r1.data=r1.data+0.02; cf.Stack{'set','dofset'}=r1; % Visualize set data in promodel stack fecom(cf,'curtab Stack','eltset');

AddTest[,-EGID i][,NodeShift,Merge,Combine]#

model=feutil('AddTest',mo1,mo2); Combine models. When combining test and analysis models you typically want to overlay a detailed finite element mesh with a coarse wire-frame representation of the test configuration. These models coming from different origins you will want combine the two models in model.

Note that the earlier objective of combining test and FEM models is now more appropriately dealt with using SensDof entries, see  section 4.7 for sensor definitions and section 3.1 for test/analysis correlation. If you aim at combining several finite element models into an assembly, with proper handling of materials, element IDs, bases,…, you should rather use the more appropriate CombineModel command.

  • By default the node sets are considered to be disjoint. New nodes are added starting from max(mo1.Node(:,1))+1 or from NodeShift+1 if the argument is specified. Thus feutil('AddTest NodeShift',mo1,mo2) adds mo2 nodes to mo1.Node while adding NodeShift to their initial identification number. The same NodeShift is added to node numbers in mo2.Elt which is appended to mo1.Elt. mo2 can be a wire frame matrix read with ufread for example.
  • With command option Merge it is assumed that some nodes are common but their numbering is not coherent. Non coincident nodes (as defined by the AddNode command) are added to mo1.Node and mo2.Elt is renumbered according to resulting model.Node. Command option Merge-Edge is used to force mid-side nodes to be common if the end nodes are. Note that command Merge will also merge all coincident nodes of mo2.
  • With command option Combine it is assumed that some nodes are common and their numbering is coherent. Nodes of mo2.Node with new NodeId values are added to mo1.Node while common NodeId values are assumed to be located at the same positions.
  • You can specify an EGID value for the elements that are added using AddTest -EGID -1 for example. In particular negative EGID values are display groups so that they will be ignored in model assembly operations. Command option keeptest allows to retain existing test frames when adding a new one. If the same EGID is declared, test frames are then combined in the same group.
  • Command option -NoOri returns model without the Info,OrigNumbering entry in the model stack.

Divide div1 div2 div3#

model=feutil('Divide div1 div2 div3',model);
Mesh refinement by division of elements. Divide applies to all groups in model.Elt. To apply the division to a selection within the model use ObjectDivide.

Division directions div1 div2 div3 are here understood in the local element basis, thus depending on the declared node orders in the connectivity matrix that refer to the reference cell. Uneven divisions as function of the direction will thus require some care regarding the element declaration if the original mesh has been heterogeneously generated.

Currently supported divisions are

  • segments : elements with beam1 parents are divided in div1 segments of equal length.
  • quadrilaterals: elements with quad4 or quadb parents are divided in a regular mesh of div1 by div2 quadrilaterals.
  • hexahedrons: elements with hexa8 or hexa20 parents are divided in a regular grid of div1 by div2 by div3 hexahedrons.
  • tria3 can be divided with an equal division of each segment specified by div1.
  • mass1 and celas elements are kept unchanged.

The Divide command applies element transformation schemes on the element parent topological structure. By default, the original element names are maintained. In case of trouble, element names can be controlled by declaring the proper parent name or use the SetGroupName command before and after divide.

The division preserves properties other than the node numbers, in addition final node numbering/ordering will depend on the MATLAB version. It is thus strongly recommended not to base meshing scripts on raw NodeId.

You can obtain unequal divisions by declaring additional arguments whose lines give the relative positions of dividers. Note that this functionality has not been implemented for quadb and tria3 elements.

For example, an unequal 2 by 3 division of a quad4 element would be obtained using
model=feutil('divide',[0 .1 1],[0 .5 .75 1],model) (see also the gartfe demo).

% Refining a mesh by dividing the elements
% Example 1 : beam1
femesh('Reset'); model=femesh('Testbeam1');  % build simple beam model
model=feutil('Divide 3',model); % divide by 3
cf=feplot(model); fecom('TextNode'); % plot model and display NodeId

% Example 2 : you may create a command string femesh('Reset'); model=femesh('Testbeam1'); % build simple beam model number=3; st=sprintf('Divide %f',number); model=feutil(st,model); cf=feplot(model); fecom('TextNode')

% Example 3 : you may use uneven division femesh('Reset'); model=femesh('Testquad4'); % one quad4 created model=feutil('Divide',model,[0 .1 .2 1],[0 .3 1]); feplot(model);

An inconsistency in division for quad elements was fixed with version 1.105, you can obtain the consistent behavior (first division along element x) by adding the option -new anywhere in the divide command.

DivideInGroups#

elt=feutil('DivideInGroups',model);
Finds groups that are not connected (no common node) and places each of these groups in a single element group.

DivideGroup i ElementSelectors#

elt=feutil('DivideGroup i ElementSelector',model);

Divides a single group i in two element groups. The first new element group is defined based on the element selectors (see section 7.12).

For example elt=feutil('divide group 1 withnode{x>10}',model);

EltId#

[EltId]=feutil('EltId',elt) returns the element identifier for each element in elt. It currently does not fill EltId for elements which do not support it.
[EltId,elt]=feutil('EltIdFix',elt) returns an elt where the element identifiers have been made unique.
Command option -elt can be used to set new EltId.

Command option -model can be used to set new EltId and renumber model Stack data, a model structure must be input, and the output is then the model.

% Handling elements IDs, renumbering elements
model=femesh('TestHexa8')
[EltId,model.Elt]=feutil('EltIdFix',model.Elt); % Fix and get EltId
[model.Elt,EltIdPos]=feutil('eltid-elt',model,EltId*18); % Set new EltId
model.Elt(EltIdPos>0,EltIdPos(EltIdPos>0)) % New EltId
% Renumber EltId with stack data
model=feutil('AddSetEltId',model,'all','groupall');
model=feutil('EltId-Model',model,EltId+1);

EltSetReplace#

Replace EltId in EltId sets with convertion table. This can be usefull when elements are modified, or refined and one would like to keep initial sets coherent with replaced parts. to ease up the procedure it is assumed that the original element sets are provided in meta-set format (see sdtweb Stack for reference).

% Define a model with clean EltId
model=femesh('testhexa8');
[eltid,model.Elt]=feutil('EltIdFix;',model);
% Generate an EltId set
model=feutil('AddSetEltId',model,'comp','groupall');
% Localize elements in model belonging to set
i1=feutil('FindElt setname comp',model);
% Get global meta-set data from model
r1=feutil('AddSetEltId-Append-get',model,'_gsel');
% Now renumber EltId
eltid(:,2)=eltid(:,1)+1e3;
model.Elt=feutil('EltId-Elt',model,eltid(:,2));
% Call EltSetReplace to update sets with new eltid
model=feutil('EltSetReplace',model,r1,eltid);
% Check that the set in model is now coherent
i2=feutil('FindElt setname comp',model);
isequal(i1,i2)

Extrude nRep tx ty tz#

Extrusion. Nodes, lines or surfaces of model are extruded nRep times with global translations tx ty tz. Elements with a mass1 parent are extruded into beams, element with a beam1 parent are extruded into quad4 elements, quad4 are extruded into hexa8, and quadb are extruded into hexa20.

You can create irregular extrusion. For example, model=feutil('Extrude 0 0 0 1',model,[0 logspace(-1,1,5)]) will create an exponentially spaced mesh in the z direction. The second argument gives the positions of the sections for an axis such that tx ty tz is the unit vector.

% Extruding mesh parts to build a model
% Example 1 : beam
femesh('Reset'); model=femesh('Testbeam1'); % one beam1 created
model=feutil('Extrude 2 1 0 0',model); % 2 extrusions in x direction
cf=feplot(model);

% Example 2 : you may create the command string number=2;step=[1 0 0]; st=sprintf('Extrude %f %f %f %f',[number step]); femesh('Reset'); model=femesh('Testbeam1'); % one beam1 created model=feutil(st,model); cf=feplot(model);

% Example 3 : you may uneven extrusions in z direction femesh('Reset'); model=femesh('Testquad4'); model=feutil('Extrude 0 0 0 1',model,[0 .1 .2 .5 1]); % 0 0 0 1 : 1 extrusion in z direction % [0 .1 .2 .5 1] : where extrusions are made feplot(model)

GetDof ElementSelectors#

Command to obtain DOF from a model, or from a list of NodeId and DOF.


Use mdof=feutil('GetDof',dof,NodeId); to generate a DOF vector from a list of DOF indices dof, a column vector (e.g. dof=[.01;.02;.03]), and a list of NodeId, a column vector. The result will be sorted by DOF, equivalent to mdof = [NodeId+dof(1);NodeId+dof(2);...].

Call mdof=feutil('GetDof',NodeId,dof); will output a DOF vector sorted by NodeId, equivalent to mdof = [NodeId(1)+dof;NodeId(2)+dof;...].


The nominal call to get DOFs used by a model is mdof=feutil('GetDOF',model). These calls are performed during assembly phases (fe_mk, fe_load, ...). This supports elements with variable DOF numbers defined through the element rows or the element property rows. To find DOFs of a part of the model, you should add a ElementSelector string to the GetDof command string.

Note that node numbers set to zero are ignored by feutil to allow elements with variable number of nodes.

FindElt ElementSelectors#

Find elements based on a number of selectors described in section 7.12. The calling format is

[ind,elt] = feutil('FindElt ElementSelector',model);

where ind gives the row numbers of the elements in model.Elt (but not the header rows except for unique superelements which are only associated to a header row) and elt (optional) the associated element description matrix.

When operators are accepted, equality and inequality operators can be used. Thus group~=[3 7] or pro < 5 are acceptable commands. See also SelElt, RemoveElt and DivideGroup, the gartfe demo, fecom selections.

FindNode Selectors#

Find node numbers based on a number of node selectors listed in section 7.11.

Different selectors can be chained using the logical operations & (finds nodes that verify both conditions), | (finds nodes that verify one or both conditions). Condition combinations are always evaluated from left to right (parentheses are not accepted).

The calling format is
[NodeId,Node] = feutil('FindNode NodeSelector',model);

Output arguments are the NodeId of the selected nodes and the selected nodes Node as a second optional output argument.

As an example you can show node numbers on the right half of the z==0 plane using the commands

fecom('TextNode',feutil('FindNode z==0 & x>0',model))

Following example puts markers on selected nodes

% Finding nodes and marking/displaying them in feplot
demosdt('demo ubeam'); cf=feplot; % load U-Beam model
fecom('ShowNodeMark',feutil('FindNode z>1.25',cf.mdl),'color','r')
fecom('ShowNodeMark-noclear',feutil('FindNode x>0.2*z|x<-0.2*z',cf.mdl),...
      'color','g','marker','o')

Note that you can give numeric arguments to the command as additional feutil arguments. Thus the command above could also have been written feutil('FindNode z== & x>=',0,0))

See also the gartfe demo.

GetEdge[Line,Patch]#

These feutil commands are used to create a model containing the 1D edges or 2D faces of a model. A typical call is

 % Generate a contour (nD-1) model from a nD model
 femesh('reset'); model=femesh('Testubeam');
 elt=feutil('GetEdgeLine',model); feutil('infoelt',elt)

GetEdgeLine supports the following variants MatId retains inter material edges, ProId retains inter property edges, Group retains inter group edges, all does not eliminate internal edges, InNode only retains edges whose node numbers are in a list given as an additional feutil argument.

These commands are used for SelEdge and SelFace element selection commands. Selface preserves the EltId and adds the FaceId after it to allow face set recovery.

GetElemF#

Header row parsing. In an element description matrix, element groups are separated by header rows (see section 7.2) which for the current group jGroup is given by elt(EGroup(jGroup),:) (one can obtain EGroup - the positions of the headers in the element matrix - using [EGroup,nGroup]=getegroup(model.Elt). The GetElemF command, whose proper calling format is

[ElemF,opt,ElemP] = feutil('GetElemF',elt(EGroup(jGroup),:),[jGroup])

returns the element/superelement name ElemF, element options opt and the parent element name ElemP. It is expected that opt(1) is the EGID (element group identifier) when defined.

Get[Line,Patch]#

Line=feutil('GetLine',node,elt) returns a matrix of lines where each row has the form [length(ind)+1 ind] plus trailing zeros, and ind gives node indices (if the argument node is not empty) or node numbers (if node is empty). elt can be an element description matrix or a connectivity line matrix (see feplot). Each row of the Line matrix corresponds to an element group or a line of a connectivity line matrix. For element description matrices, redundant lines are eliminated.

Patch=feutil('GetPatch',Node,Elt) returns a patch matrix where each row (except the first which serves as a header) has the form [n1 n2 n3 n4 EltN GroupN]. The ni give node indices (if the argument Node is not empty) or node numbers (if Node is empty). Elt must be an element description matrix. Internal patches (it is assumed that a patch declared more than once is internal) are eliminated.

The all option skips the internal edge/face elimination step. These commands are used in wire-frame and surface rendering.

GetNode Selectors#

Node=feutil('GetNode Selectors',model) returns a matrix containing nodes rather than NodeIds obtained with the FindNode command. The indices of the nodes in model.Node can be returned as a 2nd optional output argument. This command is equivalent to the feutil call

[NodeId,Node]=feutil('FindNode Selectors',model).

GetNormal[Elt,Node][,Map],GetCG#

[normal,cg]=feutil('GetNormal[elt,node]',model) returns normals to elements/nodes in model.
CG=feutil('GetCG',model) returns the CG locations. Command option -dir i can be used to specify a local orientation direction other than the normal (this is typically used for composites).
MAP=feutil('getNormal Map',model) returns a data structure with the following fields

IDcolumn of identifier (as many as rows in the .normal field). For .opt=2 contains the NodeId. For .opt=1 contains the EltId.
normalN× 3 where each row specifies a vector at ID or vertex.
opt1 for MAP at element center, 2 for map at nodes.
colorN× 1 optional real value used for color selection associated with the axes color limits.
DefLenoptional scalar giving arrow length in plot units.

The MAP data structure may be viewed using

fecom('ShowMap',MAP);fecom('ScaleOne');

Info[ ,Elt, Nodei]#

feutil('Info',model); Information on model. Info by itself gives general information about model. InfoNodei gives information about all elements that are connected to node of NodeId i.

Join[group i, EltName]#

Join the groups i or all the groups of type EltName. JoinAll joins all the groups that have the same element name. Note that with the selection by group number, you can only join groups of the same type (with the same element name). JoinAll joins all groups with identical element names.

You may join groups using there ID

% Joining groups of similar element types
femesh('Reset'); model=femesh('Test2bay');
% Join using group ID
feutil('Info',model);   % 2 groups at this step
model=feutil('JoinGroup1:2',model)  % 1 group now
feutil('Info',model);
% Join using element types
% Note you can give model (above) or element matrix (below)
femesh('Reset'); model=femesh('Test2bay'); 
model.Elt=feutil('Joinbeam1',model.Elt);  % 1 group now

Matid,ProId,MPID#

MatId=feutil('MatId',model) returns the element material identifier for each element in model.Elt.
Command MatIdNew provides a new model-wise unused material identifier. newId=feutil('MatIdNew',model);

One can also modify MatId of the model giving a third argument. model=feutil('MatId',model,r1) r1 can be a global shift on all non zero MatId or a matrix whose first column gives old MatId and second new MatId (this is not a vector for each element).

MatId renumbering is applyed to elements, model.pl and model.Stack 'mat' entries.

The ProId command works similarly.

MPId returns a matrix with three columns MatId, ProId and group numbers.
model.Elt=feutil('mpid',model,mpid) can be used to set properties of elements in model.Elt matrix.

Node[trans,rot,mir,DefShift]#

The command feutil('node [trans,rot,mir]',model,RO) allows to move model nodes (or part of a model with a provided selection) with standard transformations :

  • translation : trans x y z
  • rotation : rot x1 x2 x3 n1 n2 n3 theta with xi the coordinate of the node and ni the direction of the axe and theta the angle in degree
  • plane symmetry :
    • plane x y or z : mir x, mir y or mir z
    • point + normal : mir o x1 x2 x3 n1 n2 n3 with xi the coordinate of the node and ni the direction of the normal to the plane
    • plane equation : mir eq a b c d defining the plane aX+bY+cZ+d=0
    • best plane defined by list of node coordinates : feutil('node mir',model,struct('node',[x1 y1 z1;x2 y2 z2;...]))
    • best plane defined by list of nodeids : mir "nodeid id1 id2 id3"
  • rigid body matrix : feutil('node',model,struct('rb',[4x4 RB matrix]))

For each call, it is possible to either provide inputs as text string or as structure given on third argument with the field name corresponding to the wanted transformation.

An node selection can be provided in the text command (sel"NodeElt") or as a text in a .sel field of the RO stucture to apply the transformation on only a part of the model. See FindNode.

Here is an exhaustive list of examples

model=femesh('test tetra4'); % Load model wontaining a tetrahedron
model.Node=feutil('addnode',model.Node,[0-1 0 0]); % Add a node
model.Elt=feutil('addelt',model.Elt,'mass1',5); % Set this node as a mass1 element
feplot(model); % Display
% Displacement transformations
% translation in the direction [1 0 0] sepcified in the text command
model=feutil('node trans 1 0 0',model); feplot(model); 
% rotation of 180deg arround the axis defined by node [1 0 0] and vector [0 0 1]
RO=struct('rot',[1 0 0  0 0 1 180]); % rotation is the last number
% Only nodes in "group1" are moved
model=feutil('node -sel"group1"',model,RO); feplot(model); 
% Rigid body transformation (matrix in field rb) on nodes in group1
RO=struct('rb',[1 0 0 -1;0 1 0 0;0 0 1 0;0 0 0 1],'sel','group1');
model=feutil('node',model,RO); feplot(model); 
% mirror transformation
% Plane y=0
model=feutil('node mir y',model); feplot(model); 
% Same plane definined with node [0 0 0] and normal [0 1 0]
model=feutil('node mir o 0 0 0 0 1 0',model); feplot(model); 
% Same plane definined with nodeid 1 2 4
model=feutil('node mir nodeid 1 2 4',model); feplot(model);
% Same plane definined with equation 0*x+1*y+0*z+0=0, given as last
% argument in a structure
RO=struct('eq',[0 1 0 0]);
model=feutil('node mir',model,RO); feplot(model);
% Mirror with respect to the "best" plane passing through the node list 
RO=struct('node',[0 -0.1 0;1 0 0;0 0 1;1 0.3 1],'sel','group1');
model=feutil('node mir',model,RO); feplot(model); 
fecom('shownodemark',[0 -0.1 0;1 0 0;0 0 1;1 0.3 1]); % Show nodes defining the plane

ObjectBeamLine i, ObjectMass i#

elt=feutil('ObjectBeamLine i'); Create a group of beam1 elements. The node numbers i define a series of nodes that form a continuous beam (for discontinuities use 0), that is placed in elt as a single group of beam1 elements.

For example elt=feutil('ObjectBeamLine 1:3 0 4 5') creates a group of three beam1 elements between nodes 1 2, 2 3, and 4 5.

An alternate call is elt=feutil('ObjectBeamLine',ind) where ind is a vector containing the node numbers. You can also specify a element name other than beam1 and properties to be placed in columns 3 and more using elt=feutil('ObjectBeamLine -EltName',ind,prop).

elt=feutil('ObjectMass 1:3') creates a group of concentrated mass1 elements at the declared nodes.

% Build a mesh by addition of defined beam lines and masses
model=struct('Node',[1 0 0 0  0  0 0;   2 0 0 0  0  0 .15; ... 
                     3 0 0 0 .4  1 .176;4 0 0 0 .4 .9 .176], 'Elt',[]);
prop=[100 100 1.1 0 0]; % MatId ProId nx ny nz
model.Elt=feutil('ObjectBeamLine 1 2 0 2 3 0 3 4',prop);
% or model.Elt=feutil('ObjectBeamLine',1:4);
model.Elt=feutil('ObjectMass',model,3,[1.1 1.1 1.1]);
%model.Elt(end+1:end+size(elt,1),1:size(elt,2))=elt;
feplot(model);fecom textnode

ObjectHoleInPlate#

model=feutil('ObjectHoleInPlate ...',model);

Create a quad4 mesh of a hole in a plate. The format is 'ObjectHoleInPlate N0 N1 N2 r1 r2 ND1 ND2 NQ' giving the center node, two nodes to define the edge direction and distance, two radiuses in the direction of the two edge nodes (for elliptical holes), the number of divisions along a half quadrant of edge 1 and edge 2, the number of quadrants to fill (the figure shows 2.5 quadrants filled).
% Build a model of a plate with a hole
model=struct('Node',[1 0 0 0  0 0 0; 2 0 0 0  1 0 0; 3 0 0 0  0 2 0],'Elt',[]);
model=feutil('ObjectHoleInPlate 1 2 3 .5 .5 3 4 4',model);
model=feutil('Divide 3 4',model); % 3 divisions around, 4 divisions along radii
feplot(model)
% You could also use the call
model=struct('Node',[1 0 0 0  0 0 0; 2 0 0 0  1 0 0; 3 0 0 0  0 2 0],'Elt',[]);
%   n1 n2 n3 r1 r2 nd1 nd2 nq
r1=[ 1  2  3 .5 .5  3   4   4];
st=sprintf('ObjectHoleInPlate %f %f %f %f %f %f %f %f',r1);
model=feutil(st,model);

ObjectHoleInBlock#

model=feutil('ObjectHoleInBlock ...'); Create a hexa8 mesh of a hole in a rectangular block. The format is 'ObjectHoleInBlock x0 y0 z0 nx1 ny1 nz1 nx3 ny3 nz3 dim1 dim2 dim3 r nd1 nd2 nd3 ndr' giving the center of the block (x0 y0 z0), the directions along the first and third dimensions of the block (nx1 ny1 nz1 nx3 ny3 nz3, third dimension is along the hole), the 3 dimensions (dim1 dim2 dim3), the radius of the cylinder hole (r), the number of divisions of each dimension of the cube (nd1 nd2 nd3, the 2 first should be even) and the number of divisions along the radius (ndr).

% Build a model of a cube with a cylindrical hole
model=feutil('ObjectHoleInBlock 0 0 0  1 0 0  0 1 1  2 3 3 .7  8 8 3 2') 

Object[Quad,Beam,Hexa] MatId ProId#

model=feutil('ObjectQuad MatId ProId',model,nodes,div1,div2) Create or add a model containing quad4 elements. The user must define a rectangular domain delimited by four nodes and the division in each direction (div1 and div2). The result is a regular mesh.

For example model=feutil('ObjectQuad 10 11',nodes,4,2) returns model with 4 and 2 divisions in each direction with a MatId 10 and a ProId 11.

An alternate call is model=feutil('ObjectQuad 1 1',model,nodes,4,2): the quadrangular mesh is added to the model.

% Build a mesh based on the refinement of a single quad element
node = [0  0  0; 2  0  0; 2  3  0; 0  3  0];
model=feutil('Objectquad 1 1',node,4,3); % creates model 

node = [3 0 0; 5 0 0; 5 2 0; 3 2 0]; model=feutil('Objectquad 2 3',model,node,3,2); % matid=2, proid=3 feplot(model);

Divisions may be specified using a vector between [0,1] :

% Build a mesh based on the custom refinement of a single quad element
node = [0  0  0; 2  0  0; 2  3  0; 0  3  0];
model=feutil('Objectquad 1 1',node,[0 .2 .6 1],linspace(0,1,10)); 
feplot(model);

Other supported object topologies are beams and hexahedrons with syntaxes

model=feutil('objectbeam',model,nodes,dvx,dvy);

model=feutil('objecthexa',[Oxyz;OAxyz;OBxyz;OCxyz],divOA,divOB,divOC);

For example

% Build a mesh based on the custom refinement of a single element
node = [0  0  0; 2  0  0;1  3  0; 1  3  1];
model=feutil('Objectbeam 3 10',node(1:2,:),4); % creates model 
model=feutil('Objecthexa 4 11',model,node,3,2,5); % creates model 
feutil('infoelt',model)

Object[Arc, Annulus, Circle, Cylinder, Disk]#

These object constructors follow the format

model=feutil('ObjectAnnulus x y z r1 r2 nx ny nz Nseg NsegR',model) with x y z the coordinates of the center, nx ny nz the coordinates of the normal to the plane containing the annulus, Nseg the number of angular subdivisions, and NsegR the number of segments along the radius. The resulting model is in quad4 elements.

model=feutil('ObjectArc x y z x1 y1 z1 x2 y2 z2 Nseg obt',model) with x y z the coordinates of the center, xi yi zi the coordinates of the first and second points defining the arc boundaries, Nseg the number of angular subdivisions, and obt for obtuse, set to 1 to get the shortest arc between the two points or -1 to get the complementary arc. The resulting model is in beam1 elements.

model=feutil('ObjectCircle xc yc zc r nx ny nz Nseg',model) with xc yc zc the coordinates of the center, r the radius, nx ny nz the coordinates of the normal to the plane containing the circle, and Nseg the number of angular subdivisions. The resulting model is in beam1 elements.

model=feutil('ObjectCylinder x1 y1 z1 x2 y2 z2 r divT divZ',model) with xi yi zi the coordinates of the centers of the cylinder base and top circles, r the cylinder radius, divT the number of angular subdivisions, and divZ the number of subdivisions in the cylinder height. The resulting model is in quad4 elements.

model=feutil('ObjectDisk x y z r nx ny nz Nseg NsegR',model) with x y z, the coordinates of the center, r the disk radius, nx ny nz the coordinates of the normal to the plane containing the disk, Nseg the number of angular subdivisions, and NsegR the number of segments along the radius. The resulting model is in quad4 elements. Command option -nodeg avoids degenerate    elements by transforming them into tria3 elements.

For example:

% Build a mesh based on simple circular topologies
model=feutil('object arc 0 0 0 1 0 0 0 1 0 30 1');
model=feutil('object arc 0 0 0 1 0 0 0 1 0 30 1',model);
model=feutil('object circle 1 1 1 2 0 0 1 30',model);
model=feutil('object circle 1 1 3 2 0 0 1 30',model);
model=feutil('object cylinder 0 0 0  0 0 4 2 10 20',model);
model=feutil('object disk 0 0 0 3 0 0 1 10 3',model);
model=feutil('object disk -nodeg 1 0 0 3 0 0 1 10 3',model);
model=feutil('object annulus 0 0 0 2 3 0 0 1 10 3',model);
feplot(model)

ObjectDivide#

Applies a Divide command to a selection within the model. This is a packaged call to RefineCell, one thus has access to the following command options:

  • -MPC to generate MPC constraints to enforce displacement continuity at non conforming interfaces
  • KnownNew to add new nodes without check
  • -noSData asks no to add model stack entry info,newcEGI that provides the indices of new elements in model.
% Perform local mesh refinement
node = [0  0  0; 2  0  0; 2  3  0; 0  3  0];
model=feutil('Objectquad 1 1',node,4,3); % creates model 
model=feutil('ObjectDivide 3 2',model,'WithNode 1');
feplot(model);

% Perform a non uniform local mesh refinement with MPC node = [0 0 0; 2 0 0; 2 3 0; 0 3 0]; model=feutil('Objectquad 1 1',node,4,3); % creates model model=feutil('ObjectDivide 3 2 -MPC',model,... 'WithNode 1',[0 .2 1],[0 .25 .8 1]); % display model and MPC constraint feplot(model); fecom(';promodelinit;proviewon;') fecom('curtabCases','MPCedge');

Optim[Model, NodeNum, EltCheck]#

model.Node=feutil('Optim...',model);
model.Node=feutil('OptimModel',model) removes nodes unused in model.Elt from model.Node.

This command is very partial, a thorough model optimization is obtained using feutilb SubModel with groupall selection. model=feutilb('SubModel',model,'groupall');. To recover used nodes the most complete command is feutilb GetUsedNodes.

model.Node=feutil('OptimNodeNum',model) does a permutation of nodes in model.Node such that the expected matrix bandwidth is smaller. This is only useful to export models, since here DOF renumbering is performed by fe_mk.
model=feutil('OptimEltCheck',model) attempts to fix geometry pathologies (warped elements) in quad4, hexa8 and penta6 elements.

model=feutil('OptimDegen',model) detects degenerate elements and replaces them by the proper lower node number case hexa -> penta.

Orient, Orient i [ , n nx ny nz]#

Orient elements. For volumes and 2-D elements which have a defined orientation model.Elt=feutil('Orient',model) calls element functions with standard material properties to determine negative volume orientation and permute nodes if needed. This is in particular needed when generating models via Extrude or Divide operations which do not necessarily result in appropriate orientation (see integrules). When elements are too distorted, you may have a locally negative volume. A warning about warped volumes is then passed. You should then correct your mesh.

Note that for 2D meshes you need to use 2D element names (q4p, t3p, ...) rather than quad4, tria3, .... Typically model.Elt=feutil('setgroup1 name q4p',model).

Orient normal of shell elements. For plate/shell elements (elements with parents of type quad4, quadb or tria3) in groups i of model.Elt, model.Elt=feutil('Orient i n nx ny nz',model) command computes the local normal and checks whether it is directed towards the node located at nx ny nz. If not, the element nodes are permuted to that a proper orientation is achieved. A -neg option can be added at the end of the command to force orientation away rather than towards the nearest node.

model.Elt=feutil('Orient i',model,node) can also be used to specify a list of orientation nodes. For each element, the closest node in node is then used for the orientation. node can be a standard 7 column node matrix or just have 3 columns with global positions.

For example

% Specify element orientation
% Load example
femesh('Reset'); model=femesh('Testquad4'); 
model=feutil('Divide 2 3',model);
model.Elt=feutil('Dividegroup1 WithNode1',model); 
% Orient elements in group 2 away from [0 0 -1]
model.Elt=feutil('Orient 2 n 0 0 -1 -neg',model);
MAP=feutil('GetNormal MAP',model);MAP.normal

Quad2Lin, Lin2Quad, Quad2Tria, etc.#

Basic element type transformations.

model=feutil('Lin2Quad epsl .01',model) is the generic command to generate second order meshes.
Lin2QuadCyl places the mid-nodes on cylindrical arcs.
Lin2QuadKnownNew can be used to get much faster results if it is known that none of the new mid-edge nodes is coincident with an existing node. Quad2Lin performs the inverse operation.

For this specific command many nodes become unecessary, command option -optim performs a cleanup by removing these nodes from the model, and its Stack and Case entries.

Quad2Tria searches elements for quad4 element groups and replaces them with equivalent tria3 element groups.
Hexa2Tetra replaces each hexa8 element by 24 tetra4 elements (this is really not a smart thing to do).
Hexa2Penta replaces each hexa8 element by 6 tetra4 elements (warning : this transformation may lead to incompatibilities on the triangular faces).
Penta2Tetra replaces each penta6 element by 11 tetra4 elements.

Command option KnownNew can be used for Hexa2Tetra, Hexa2Penta, and Penta2Tetra. Since these commands add nodes to the structure, quicker results can be obtained if it is known that none of the new nodes are coincident with existing ones. In a more general manner, this command option is useful if the initial model features coincident but free surfaces (e.g. two solids non connected by topology, when using coupling matrices). The default behavior will add only one node for both surfaces thus coupling them, while the KnownNew alternative will add one for each.

% Transforming elements in a mesh, element type and order
% create 2x3 quad4 
femesh('Reset'); model=femesh('Testquad4');
model=feutil('Divide 2 3',model);
model=feutil('Quad2Tria',model); % conversion
feplot(model)
% create a quad, transform to triangles, divide each triangle in 4
femesh('Reset'); model=femesh('Testquad4');
model=feutil('Quad2Tria',model);
model=feutil('Divide2',model);
cf=feplot(model); cf.model
% create a hexa8 and transform to hexa20
femesh('Reset'); model=femesh('Testhexa8');
model=feutil('Lin2Quad epsl .01',model);
feutil('InfoElt',model)

RefineCell, Beam l, ToQuad#

  • The RefineCell command is a generic element-wise mesh refinement command. Each element can be replaced by another mesh fitted in the initial topology. This is in particular used by RefineToQuad.

    For each element type, it is possible to define an interior mesh defined in the element reference configuration. RefineCell then applies node and element additions in an optimized way to produce a final mesh in which all elements have been transformed.

    A typical syntax is model=feutil('RefineCell',model,R1), with model a standard SDT model and R1 a running option structure providing in particular the cell refinement topologies.

    In practice, cell refinement is defined for each element type in the reference configuration, giving additional nodes by edge, then face, then volume in increasing index. New nodes are computed using an operator performing weighted sums of initial cell coordinates. If no weights are given, arithmetic average is used.

    Option structure R1 contains fields named as element types. These fields provide structures with fields

    • edge a cell array in the format {[newId [oldId_Av]], [weights]} providing the nodes to be added on the edges of the initial element. It is a 1 by 2 cell array. The first part is a matrix with as many lines as new nodes to be added, the first column newId providing the new NodeId of the reference configuration and the following ones oldId_Av the nodes of the initial cell used to generate the new coordinates. The second part is a weight matrix, with as many lines as new nodes and as many columns as oldId_Av providing the weights for each node. The weights matrix can be left empty in which case equal weights will be used for each nodes. It can also be set a a scalar, and in this case the scalar coefficient will be used for each weight. newId have to be given in increasing order. This can be left blank if no node has to be added in edges.
    • face a cell array in the same format than for field edge, providing the nodes to be added on the edges of the initial element. newId have to be given in increasing order and greater than the edge new IDs. This can be left blank if no node has to be added in faces.
    • volume a cell array in the same format than for field edge, providing the nodes to be added in the volume of the initial element. newId have to be given in increasing order and greater than the edge new IDs and greater than the face new IDs. This can be left blank if no node has to be added in the volume.
    • Elt a cell array providing the elements defined in the reference configuration topology. This is a cell array in format {ElemP, Elt}, ElemP providing the new element types and Elt an element matrix with no header providing the connectivies associated to ElemP.
    • faces For non symmetric transformations, it is possible to define a reference node ordering of the reference configuration that allows identifying a reference face of the reference configuration.
    • shift For non symmetric transformations, shift will identify the reference face in the faces field to allow transformation for selected faces of elements.

    A sample call to refine quad4 elements using RefineCell is then

    % refine cell sample call for iso quad refinement
    model=femesh('testquad4'); % base quad element
    % definition of the quad transformation
    R1=struct('quad4',...
     struct('edge',{{[5 1 2;6 2 3;7 3 4;8 4 1],.5}},...
     'face',{{[9 1 2 3 4],.25}},...
     'Elt',{{'quad4',[1 5 9 8;5 2 6 9;9 6 3 7;9 7 4 8]}}));
    mo1=feutil('refinecell',model,R1)
    [eltid,mo1.Elt]=feutil('EltIdFix;',mo1);
    % Visualization
    cf=feplot(mo1); fecom('textnode')
    

    It is possible to restrain refinement to an element selection. This is realized by adding field set to R1 containing a list of EltId on which the refinement will be performed.

    By default, the output model only contains the refined elements.

    The following command options are available

    • -Replaceval outputs the complete model on which selected elements have been refined. In this latter case, apparition of non conforming interfaces is possible. Set val to 2 to preserve properties stored in the model Stack.
    • -MPC allows generating MPC constraints (on DOF 1,2,3) at non-conforming interfaces to enforce displacement continuity. Generated MPC are named MPCedge and MPCface respectively concerning nodes added on edges and faces.
    • -mpcALL generates MPC entries relative to all new nodes (DOF 1,2,3). This allows field projection from the original mesh to the refined one. Generated MPC are named MPCedge, MPCface and MPCvolume respectively concerning nodes added on edges, faces and volumes.
    • keepEP preserves elements properties assignements based on the initial elements.
    • keepSets preserves element sets by expanding all replaced elements by their refined versions in all sets.
    • AllElts to force working on all element types whatever the input topologies. Missing ones will use the RefineToQuad strategiy.
    • given in combination with AllElts not to use the RefineToQuad strategiy on missing topologies.
    • KnownNew new nodes are not merged.
    % local refine cell call with MPC generation
    R1.set=[1]; % define an EltId set to refine
    % call for MPC for new interface edges
    mo1=feutil('refinecell-replace-mpc',mo1,R1);
    % display refined model and MPC
    cf=feplot(mo1);
    fecom(cf,';promodelinit;proviewon;curtabCase;','MPCedge');
    

    Command option KnownNew adds new nodes without merging overlaying ones.

    Command option -keepEP asks to keep the element type (instead of the parent one) possible only if the refined cell features element sharing the same parent type than the initial element.

    Command option -keepSets asks to keep EltId sets coherence by replacing original element IDs in the sets with the refined cell ones.


    Non symmetric cell refinement requires the ability to detect the element orientation regarding the reference cell orientation. The strategy implemented is based on element face (for volume) or edge (for shells) identification, through the definition in the input structure of a field faces providing the face indices of the reference model and a shift index providing a reference face used in the reference cell. One can provide as many reference faces as necessary to uniquely define the reference cell orientation.

    In this case, each element to be refined must be assigned a face (or edge) list selection for orientation purpose, with as many faces as specified in the .shift field. The field set in input structure R1 is then mandatory with as many additional columns as the number of reference cell, the first one providing the selected element IDs and the following ones the face (or edge) identifier corresponding (including order) to the reference cell orientation face. See feutil AddSetFaceId, and FindElt commands to generate such element selection.

    The following example provides a non-symmetric cell refinement of a side of a structure allowing an increase of node one side while keeping a continuous mesh.

    % unsymmetric refine cell call
    model=femesh('testquad4'); % base model
    model=feutil('refineToQuad',model); % refine into 4 quad4
    % fix eltid for clean element selection
    [eltid,model.Elt]=feutil('EltIdFix;',model);
    % define a non symmetric cell refinement
    % here refinement is based on edge 1 2 using reference faces
    R1=struct('quad4',...
     struct('edge',{{[5 1 2;6 1 2],...
     [2/3 1/3;1/3 2/3]}},...
     'face',{{[7 1:4;8 1:4],...
    [1/6 1/3 1/3 1/6;1/3 1/6 1/6 1/3]}},...
    'Elt',{{'quad4',[1 5 8 4;5 6 7 8;6 2 3 7;8 7 3 4]}},...
    'faces',quad4('edge'),'shift',1));
    

    % define a selection of edges to refine elt=feutil('selelt seledge & innode{x==0}',model); % here easy recovery on elements for edge selection % based on shell element R1.set=elt(2:end,5:6); % call refinement mo1=feutil('refinecell-replace',model,R1) cf=feplot(mo1); fecom('textnode')

  • The RefineBeam command searches model.Elt for beam elements and divides elements so that no element is longer than l. For beam1 elements, transfer of pin flags properties are forwarded by keeping non null flags on the new beam elements for which a pre-existing node was flagged.
    % Specific mesh refinement for beam
    femesh('Reset'); model=femesh('Testbeam1'); % create a beam
    model=feutil('RefineBeam 0.1',model);
    

    One can give a model sub-selection (FindElt command string) as 2nd argument, to refine only a part of the model beams.

  • The RefineBeamUnival command uniformly refines all beam1elements into val elements. This command packages a feutil ObjectDivide call with command options KnownNew and -noSData.
    • Command option -pin allows proper pin flag forwarding for beam1 elements. transfer of pin flags properties are forwarded by keeping non null flags on the new beam elements for which a pre-existing node was flagged. This constitutes the main interest of the command.
    • Command option -MergeNew asks to merge new nodes instead of simply adding them.
  • The RefineToQuad command transforms first order triangles, quadrangles, penta, tetra, and hexa to quad and hexa only while dividing each element each in two. The result is a conform mesh, be aware however that nodes can be added to your model boundaries. Using such command on model sub-parts will thus generate non conforming interfaces between the refined and non-refined parts.

    By default, new nodes are added with an AddNode command so matched new nodes are merged. Command option KnownNew allows a direct addition of new nodes without checking.

    % Refining mesh and transforming to quadrangle elements
    model=femesh('testtetra4');model=feutil('RefineToQuad',model);
    feplot(model);
    

RefineLinelc#

The RefineLine generates line uniform refinements in the provided line segments, so that gaps between two points along the provided line are not higher than a given characteristic length. This is useful for mesh seeding. Command option -tolMergeval allows merging points with gaps under the given tolerance, this can occur when providing merged series of points.

% Generate a line in 0-100 with fixed intermediate position at 32, with a maximum setp of 12.5
r1=feutil('RefineLine 12.5',[0 32 100])
% now with two given positions
r1=feutil('RefineLine 12.5',[0 32 33 100])
% merge points with gaps under2
r1=feutil('RefineLine 12.5 -tolMerge2',[0 32 33 100])

RemoveElt ElementSelectors#

[model.Elt,RemovedElt]=feutil('RemoveElt ElementSelectors',model)'

Element removal. This function searches model.Elt for elements which verify certain properties selected by ElementSelectors as a FindElt string, and removes these elements from the model description matrix. 2nd output argument RemovedElt is optional and contains removed elements. A sample call would be

% Removing elements in a model
% create 3x2 quad4 
femesh('Reset'); model=femesh('Testquad4');model=feutil('Divide 2 3',model); 
[model.Elt,RemovedElt]=feutil('RemoveElt WithNode 1',model);
feplot(model)

Remove [Pro, Mat] MatId, ProId#

Mat, Pro removal This function takes in argument the ID of a material or integration property and removes the corresponding entries in the model pl/il fields and in the stack mat/pro entries.

  • Command option -all removes all pl/il entries found in the model and its stack.
  • Command option -unused removes all pl/il entries not used by any element.

This call supports the info, Rayleigh stack entry (see sdtweb damp), so that the data entries referring to removed IDs will also be removed. By default, the non-linear properties are treated like normal properties. Care must thus be taken if a non-linear property that is not linked to specific elements is used. Command option -unused will alter this behavior and keep non-linear properties.

Sample calls are provided in the following to illustrate the use.

% Removing material and integration properties in a model
model=femesh('testhexa8');
model=stack_set(model,'pro','integ',p_solid('default'));
model=stack_set(model,'mat','steel',m_elastic('default steel'));
model=feutil('remove pro 110',model);
model=feutil('remove pro',model,111);
model=feutil('remove mat 100',model);
model=feutil('remove mat 100 pro 1',model);
model=feutil('remove pro -all',model); % Command option -all
model=feutil('remove mat pro -all',model);
model=femesh('testhexa8'); % Command option -unused
model=feutil('remove mat pro -unused',model);

Renumber#

model=feutil('Renumber',model'NewNodeNumbers) can be used to change the node numbers in the model. Currently nodes, elements, DOFs and deformations, nodeset, par, cyclic and other Case entries are renumbered.

NewNodeNumbers is the total new NodeIds vector. NewNodeNumbers can also be a scalar and then defines a global NodeId shifting. If NewNodeNumbers has two columns, first giving old NodeIds and second new NodeIds, a selective node renumbering is performed.

If NewNodeNumbers is not provided values 1:size(model.Node,1) are used. This command can be used to meet the OpenFEM requirement that node numbers be less than 2^31/100. Another application is to joint disjoint models with coincident nodes using

Command option -NoOri asks not to add the info,OrigNumbering data in the model stack. info,OrigNumbering is only useful when the user needs to convert something specific linked to the new node numerotation that is outside model.

% Finding duplicate nodes and merging them
[r1,i2]=feutil('AddNode',model.Node,model.Node);
model=feutil('Renumber',model,r1(i2,1));

Renumbering can also be applied to deformation curves, using the same syntax. Be aware however that to keep coherence between a deformation curve and a renumbered model, one should input NewNodeNumbers as the renumbered model stack entry info,OrigNumbering.

% Renumering the nodes of a model, and its data
% simple model
model=femesh('testhexa8b');
% simple curve
def=fe_eig(model,[5 5 1e3]);
% first renumber model
model=feutil('renumber',model,1e4);
% then renumber def with renumbering info
r1=stack_get(model,'info','OrigNumbering','get');
def=feutil('renumber',def,r1);

RepeatSel nITE tx ty tz#

Element group translation/duplication. RepeatSel repeats the elements of input model nITE times with global axis translations tx ty tz between each repetition of the group. If needed, new nodes are added to model.Node. An example is treated in the d_truss demo.

% Build a mesh by replicating and moving sub-parts
femesh('Reset'); model=femesh('Testquad4');
model=feutil('Divide 2 3',model); 
model=feutil('RepeatSel 3 2 0 0',model); % 3 repetitions, tx=2
feplot(model)
% an alternate call would be
%                                            number, direction
% model=feutil(sprintf('Repeatsel %f %f %f %f', 3,  [2 0 0]))

Rev nDiv OrigID Ang nx ny nz#

Revolution. The elements of model are taken to be the first meridian. Other meridians are created by rotating around an axis passing trough the node of number OrigID (or the origin of the global coordinate system) and of direction [nx ny nz] (the default is the z axis [0 0 1]). nDiv+1 (for closed circle cases ang=360, the first and last are the same) meridians are distributed on a sector of angular width Ang (in degrees). Meridians are linked by elements in a fashion similar to extrusion. Elements with a mass1 parent are extruded into beams, element with a beam1 parent are extruded into quad4 elements, quad4 are extruded into hexa8, and quadb are extruded into hexa20.

The origin can also be specified by the x y z values preceded by an o using a command like model=feutil('Rev 10 o 1.0 0.0 0.0 360 1 0 0').

You can obtain an uneven distribution of angles using a second argument. For example model=feutil('Rev 0 101 40 0 0 1',model,[0 .25 .5 1]) will rotate around an axis passing by node 101 in direction z and place meridians at angles 0 10 20 and 40 degrees.

% Build a mesh by revolving a sub-part
model=struct('Node',[1 0 0 0  .2 0   0; 2 0 0 0  .5 1 0; ...  
                     3 0 0 0  .5 1.5 0; 4 0 0 0  .3 2 0],'Elt',[]);
model.Elt=feutil('ObjectBeamLine',1:4);
model=feutil('Divide 3',model);
model=feutil('Rev 40 o 0 0 0 360 0 1 0',model);
feplot(model)
fecom(';triax;view 3;showpatch')
% An alternate calling format would be
%      divi origin angle direct
% r1 = [40  0 0 0  360   0 1 0];
% model=feutil(sprintf('Rev %f o %f %f %f %f %f %f %f',r1))

RotateNode OrigID Ang nx ny nz#

Rotation. The nodes of model are rotated by the angle Ang (degrees) around an axis passing trough the node of number OrigID (or the origin of the global coordinate system) and of direction [nx ny nz] (the default is the z axis [0 0 1]). The origin can also be specified by the x y z values preceded by an o model=feutil('RotateNode o 2.0 2.0 2.0 90 1 0 0',model) One can define as a second argument a list of NodeId or a FindNode string command to apply rotation on a selected set of nodes. model=feutil('RotateNode o 2.0 2.0 2.0 90 1 0 0',model,'x==1')

For example:

% Rotating somes nodes in a model
femesh('reset'); model=femesh('Testquad4'); model=feutil('Divide 2 3',model); 
% center is node 1, angle 30, aound axis z
%                                     Center angle  dir
st=sprintf('RotateNode %f %f %f %f %f',[1      30   0 0 1]);
model=feutil(st,model);  
feplot(model); fecom(';triax;textnode'); axis on

Similar operations can be realized using command basisgnode.

SelElt ElementSelectors#

elt=feutil('SelElt ElementSelectors',model)

Element selection. SelElt extract selected element from model that verify certain conditions. Available element selection commands are described under the FindElt command and section 7.12.

SetSel[Mat j, Pro k]#

Set properties of an element selection. For a set of elements selected using a FindElt string command, you can modify the material property identifier j and/or the element property identifier k. For example

 % Assigning element properties to an element selection
 model=femesh('Testubeam')
 % Set MatId 10 and ProId 10 to all elements with z>1
 model.Elt=feutil('SetSel Mat10 Pro10',model,'withnode{z>1}');
 cf=feplot(model); 
 fecom(cf,'colordatamat'); % show matid with different colors

SetGroup[i,name] [Mat j, Pro k, EGID e, Name s]#

Set properties of a group. For group(s) selected by number i, name name, or all you can modify the material property identifier j, the element property identifier k of all elements and/or the element group identifier e or name s. For example

 % Assigning element properties by groups
 model.Elt=feutil('SetGroup1:3 Pro 4',model);
 model.Elt=feutil('SetGroup rigid Name celas',model) 

If you know the column of a set of element rows that you want to modify, calls of the form model.Elt(feutil('FindElt Selectors',model), Column)= Value can also be used.

 % Low level assignment of element properties
 femesh('Reset'); model=femesh('Testubeamplot');
 model.Elt(feutil('FindElt WithNode{x==-.5}',model),9)=2;
 cf=feplot(model); 
 cf.sel={'groupall','colordatamat'};

See MPID for higher level custom element properties assignments.

SetPro,SetMat,GetPro,GetMat#

Set an integration property data (ProId) or material property (MatId) to the model (enrich the list of matid and proid). You can modify an il or pl property of ID i by giving its name and its value using an integrated call of the type

% Specifying material/integration rule parameters in a model
 model=femesh('testhexa8');model.il
 model=feutil('SetPro 111 IN=2',model,'MAP',struct('dir',1,'DOF',.01),'NLdata',struct('type','nl_inout'));
 feutilb('_writeil',model)
 % Now edit specific NLdata fields
 model=feutil('SetPro 111',model,'NLdataEdit',struct('Fu','Edited'));model.Stack{end}.NLdata
 mat=feutil('GetPl 100 -struct1',model) % Get Mat 100 as struct

The names related to the integration properties a documented in the p_functions, p_solid, p_shell, p_beam, ... To get a type use calls of the form p_pbeam('PropertyUnitTypeCell',1).

The command can also be used to define additional property information : pro.MAP for field at nodes (section ??), gstate for field at integration points and NLdata for non linear behavior data (nl_spring).

The GetPro and GetMat commands are the pending commands. For example:

 model=femesh('testhexa8');model.il
 rho=feutil('GetMat 100 rho',model) % get volumic mass
 integ=feutil('GetPro 111 IN',model) % get the integ rule

To assign proid and matid defined in the model to specific elements, see feutil SetSel and SetGroup.

GetIl,GetPl#

The commands GetIl and GetPl respectively output the il and pl matrices of the model for the IDs used by elements. This command provides the values used during assembling procedures and aggregates the values stores in the model.il, model.pl fields and pro, mat entries in the model stack.

StringDOF#

feutil('stringdof',sdof) returns a cell array with cells containing string descriptions of the DOFs in sdof.

SymSel OrigID nx ny nz#

Plane symmetry. SymSel replaces elements in FEel0 by elements symmetric with respect to a plane going through the node of number OrigID (node 0 is taken to be the origin of the global coordinate system) and normal to the vector [nx ny nz]. If needed, new nodes are added to FEnode. Related commands are TransSel, RotateSel and RepeatSel.

Trace2Elt#

elt=feutil('Trace2Elt',ldraw);
Convert the ldraw trace line matrix (see ufread 82 for format details) to element matrix with beam1 elements. For example:

% Build a beam model from a trace line matrix
TEST.Node=[1001 0 0 0 0 0 0    ; 1003 0 0 0 0.2 0 0 ;
           1007 0 0 0 0.6 0 0  ; 1009 0 0 0 0.8 0 0 ;
           1015 0 0 0 0 0.2 0  ; 1016 0 0 0 0.2 0.2 0;
           1018 0 0 0 0.6 0.2 0; 1019 0 0 0 0.8 0.2 0]; 
L=[1001 1003 1007 1009];  
ldraw(1,[1 82+[1:length(L)]])=[length(L) L]; 
L=[1015 1016 1018 1019];
ldraw(2,[1 82+[1:length(L)]])=[length(L) L]; 
L=[1015 1001 0 1016 1003 0 1018 1007 0 1019 1009 0];
ldraw(3,[1 82+[1:length(L)]])=[length(L) L];
TEST.Elt=feutil('Trace2Elt',ldraw);
cf=feplot(TEST)

TransSel tx ty tz#

Translation of the selected element groups. TransSel replaces elements by their translation of a vector [tx ty tz] (in global coordinates). If needed, new nodes are added. Related commands are SymSel, RotateSel and RepeatSel.

% Translate and transform a mesh part
femesh('Reset'); model=femesh('Testquad4'); model=feutil('Divide 2 3',model); 
model=feutil('TransSel 3 1 0',model); % Translation of [3 1 0]
feplot(model); fecom(';triax;textnode')

Please, note that this command is usefull to translate only part of a model. If the full model must be translated, use basiscommand gnode. An example is given below.

% Translate all nodes of a model
femesh('Reset'); model=femesh('Testquad4'); model=feutil('Divide 2 3',model); 
model.Node=basis('gnode','tx=3;ty=1;tz=0;',model.Node);
feplot(model); fecom(';triax;textnode')

UnJoin Gp1 Gp2#

Duplicate nodes which are common to two element ensembles. To allow the creation of interfaces with partial coupling of nodal degrees of freedom, UnJoin determines which nodes are common to the specified element ensembles.

The command duplicates the common nodes between the specified element ensembles, and changes the node numbers of the second element ensemble to correspond to the duplicate set of nodes. The optional second output argument provides a two column matrix that gives the correspondence between the initial nodes and the duplicate ones. This matrix is coherent with the OrigNumbering matrix format.

The following syntaxes are accepted

  • [model,interNodes]=feutil('unjoin Gp1 Gp2',model)' Implicit group separation, Gp1 (resp. Gp2) is the group identifier (as integer) of the first (resp. second) element groups to unjoin.
  • [model,interNodes]=feutil('unjoin',model,EltSel1,EltSel2); Separation of two element selections. EltSel1 (resp. EltSel2) are either FindElt strings or EltId vectors providing the element selections corresponding to each ensemble.
  • [model,interNodes=feutil('unjoin',model,RA); general input with RA as a structure. RA has fields
    • .type, either group, eltid or eltind that provides the type of data for the selections, set to eltid if omitted.
    • .sel1, definition of the first element ensemble, the GroupId for type group, either a FindElt string or a vector of EltId or EltInd depending on field .type.
    • .sel2, definition of the second element ensemble, same format as field .sel1.
    • .NodeSel, provides a FindNode selection command to restrict the second element ensemble. Optional, set to groupall by default
 % Generate a disjointed interface between to parts in a model
femesh('Reset'); model=femesh('Test2bay');
feutil('FindNode group1 & group2',model) % nodes 3 4 are common

% Implicit call for group mo1=feutil('UnJoin 1 2',model); feutil('FindNode group1 & group2',mo1) % no common nodes in unjoined model

% Variant by specifying selections mo1=feutil('UnJoin',model,'group 1','group 2'); feutil('FindNode group1 & group2',mo1) % no common nodes in unjoined model

% Variant with structure input, type "group" RA=struct('type','group','sel1',1,'sel2',2); mo1=feutil('UnJoin',model,RA); feutil('FindNode group1 & group2',mo1) % no common nodes in unjoined model

% Variant with structure input, type "eltid" and string selections RA=struct('type','eltid','sel1','group1','sel2','group 2'); mo1=feutil('UnJoin',model,RA); feutil('FindNode group1 & group2',mo1) % no common nodes in unjoined model

% Advanced variants with structure and with selections as vectors % Clean model EltId [eltid,model.Elt]=feutil('eltidfix;',model); i1=feutil('findelt group1',model); i2=feutil('findelt group2',model);

% type "eltid" RA=struct('type','eltid','sel1',eltid(i1),'sel2',eltid(i2)); mo1=feutil('UnJoin',model,RA); feutil('FindNode group1 & group2',mo1) % no common nodes in unjoined model

% type "eltind" RA=struct('type','eltind','sel1',i1,'sel2',i2); mo1=feutil('UnJoin',model,RA); feutil('FindNode group1 & group2',mo1) % no common nodes in unjoined model

See also

feutila, fe_mk, fecom, feplot, section 4.5, demos gartfe, d_ubeam, beambar ...