Commit 48c87a51 authored by Philipp Schäfer's avatar Philipp Schäfer

itaComsolNode

-now can also represent a node that is not on first level (e.g. result.export)
-now can access Children via tag, name or index
-cleaned up Static functions:
  -Functions that only work on feature nodes are declared properly now
  -Removed outdated helper functions
  -properly grouped helper functions
parent 7addece8
classdef (Abstract)itaComsolNode < handle
%itaComsolRootNode Abstract class that represents a first level
%node of a Comsol model tree. These elements again can hold
%itaComsolRootNode Abstract class that represents a node of a Comsol
%model tree (usually at first level). These elements again can hold
%multiple Comsol nodes.
% Also provides basic methods to work on Comsol nodes
%
......@@ -19,11 +19,15 @@ classdef (Abstract)itaComsolNode < handle
properties(Access = protected)
mModel; %itaComsolModel object
mActiveNode; %Active comsol node
mParentNode; %Corresponding parent node. For first level nodes this equals modelNode
end
properties(Access = private)
mListNodeTag;
mNodeClassName;
end
properties(Dependent = true, Access = private)
rootNode; %Node containing the children (=obj.mParentNode.(obj.mListNodeTag))
end
properties(Dependent = true, Access = protected)
modelNode; %Comsol model node (= mModel.modelNode)
end
......@@ -33,26 +37,35 @@ classdef (Abstract)itaComsolNode < handle
%% Constructor
methods
function obj = itaComsolNode(comsolModel, listTag, nodeClassName)
function obj = itaComsolNode(comsolModel, listTag, nodeClassName, parentNode)
assert(isa(comsolModel, 'itaComsolModel') && isscalar(comsolModel),...
'First input must be an itaComsolModel')
assert(ischar(listTag) && isrow(listTag), 'Second input must be a char row vector')
assert(ischar(nodeClassName) && isrow(nodeClassName), 'Third input must be a char row vector')
if nargin == 3; parentNode = comsolModel.modelNode; end
assert(isempty(parentNode) || contains(class(parentNode), 'com.comsol.clientapi.impl.'), 'Fourth input must be a comsol node')
obj.mModel = comsolModel;
obj.mListNodeTag = listTag;
obj.mNodeClassName = nodeClassName;
obj.mParentNode = parentNode;
obj.mActiveNode = obj.First();
end
end
%% Accessing comsol nodes
%% Dependent nodes
methods
function modelNode = get.modelNode(obj)
modelNode = obj.mModel.modelNode;
end
function rootNode = get.rootNode(obj)
rootNode = obj.mParentNode.(obj.mListNodeTag);
end
end
%% Accessing Children
methods
function comsolNode = get.activeNode(obj)
comsolNode = obj.mActiveNode;
end
......@@ -63,11 +76,68 @@ classdef (Abstract)itaComsolNode < handle
function comsolNode = First(obj)
%Returns the first child node
comsolNode = obj.getFirstRootElementChild(obj.mListNodeTag);
% Returns [] if no child exists
comsolNode = [];
tags = obj.getRootTags();
if isempty(tags); return; end
comsolNode = obj.getRootChildByTag(tags(1));
end
function comsolNodeCellArray = All(obj)
%Returns all child nodes as cell array
comsolNodeCellArray = obj.getRootElementChildren(obj.mListNodeTag);
tags = obj.getRootTags();
comsolNodeCellArray = cell(1, numel(tags));
for idxNode = 1:numel(tags)
comsolNodeCellArray{idxNode} = obj.getRootChildByTag(tags(idxNode));
end
end
function comsolNode = Child(obj, tag)
%Returns a specific child giving its tag
% Returns [] if child does not exist
assert(ischar(tag) && isrow(tag), 'Input must be a char row vector')
comsolNode = [];
if obj.hasChildNode(obj.rootNode, tag)
comsolNode = obj.getRootChildByTag(tag);
end
end
function comsolNode = ChildByName(obj, name)
%Returns a specific child giving its name/label
% Returns [] if child does not exist
assert(ischar(name) && isrow(name), 'Input must be a char row vector')
comsolNode = [];
childNodes = obj.All();
for idxNode = 1:numel(childNodes)
currentNode = childNodes{idxNode};
if strcmp(currentNode.name(), name)
comsolNode = currentNode;
return;
end
end
end
function comsolNode = ChildByIndex(obj, idx)
%Returns a specific child giving its index
% Throws an error if index exceeds boundaries
assert(isnumeric(idx) && isscalar(idx) && mod(idx,1)==0 && idx > 0,...
'Input must be a single integer')
childNodes = obj.All();
assert( idx <= numel(childNodes), 'Index exceeds number of children')
comsolNode = childNodes{idx};
end
function names = ChildNames(obj)
%Returns the names/labels of all child nodes as cell array
childNodes = obj.All();
names = cell(size(childNodes));
for idxNode = 1:numel(childNodes)
names{idxNode} = char( childNodes{idxNode}.name );
end
end
end
methods(Access = private)
function tags = getRootTags(obj)
tags = obj.getChildNodeTags(obj.rootNode);
end
function comsolNode = getRootChildByTag(obj, tag)
comsolNode = obj.mParentNode.(obj.mListNodeTag)(tag);
end
end
......@@ -86,52 +156,10 @@ classdef (Abstract)itaComsolNode < handle
end
end
%% -----------Helper Function Section------------------------------- %%
%% Root node functions
methods(Access = private)
function nodes = getRootElementChildren(obj, rootName)
tags = obj.getChildNodeTags(obj.modelNode.(rootName));
nodes = cell(1, numel(tags));
for idxNode = 1:numel(tags)
nodes{idxNode} = obj.modelNode.(rootName)(tags(idxNode));
end
end
function node = getFirstRootElementChild(obj, rootName)
node = [];
tags = obj.getChildNodeTags(obj.modelNode.(rootName));
if isempty(tags); return; end
node = obj.modelNode.(rootName)(tags(1));
end
end
%% Functions applying directly to model nodes
%% -----------Helper Function Section------------------------------- %%
%% Static functions applying directly to model nodes
methods(Access = protected, Static = true)
function childNodes = getChildNodes(comsolNode)
tags = itaComsolNode.getChildNodeTags(comsolNode);
childNodes = cell(1, numel(tags));
for idxNode = 1:numel(tags)
if ismethod(comsolNode, 'feature')
childNodes{idxNode} = comsolNode.feature(tags(idxNode));
else
childNodes{idxNode} = comsolNode(tags(idxNode));
end
end
end
function childNodes = getChildNodesByType(comsolNode, type)
tags = itaComsolNode.getChildNodeTags(comsolNode);
childNodes = {};
for idxTag = 1:numel(tags)
if ismethod(comsolNode, 'feature')
node = comsolNode.feature(tags(idxTag));
else
node = comsolNode(tags(idxTag));
end
if strcmp(node.getType, type)
childNodes{end+1} = node;
end
end
end
%% Children
function out = getChildNodeTags(comsolNode)
itaComsolNode.checkInputForComsolNode(comsolNode);
......@@ -149,19 +177,37 @@ classdef (Abstract)itaComsolNode < handle
end
end
function out = getNodeType(comsolNode)
function [bool] = hasChildNode(comsolNode, childTag)
itaComsolNode.checkInputForComsolNode(comsolNode);
if strcmp(comsolNode.scope(), 'root')
warning('Root objects do not have a type. Returning name instead.')
out = comsolNode.name();
elseif ismethod( comsolNode, 'feature' )
out = itaComsolNode.getNodeType( comsolNode.feature() );
elseif ismethod( comsolNode, 'getType' )
out = comsolNode.getType();
else
error(['Comsol Node of type "' class(comsolNode) '" does not seem to have a function to return a type'])
bool = false;
if ~ismethod(comsolNode, 'tags'); return; end
tags = cell(comsolNode.tags);
idxTag = strcmp(tags, childTag);
if sum(idxTag) ~=1; return; end
bool = true;
end
%% Nodes with features
function childNodes = getFeatureNodes(comsolNode)
assert(ismethod(comsolNode, 'feature'), 'Given Comsol node does not have features')
tags = itaComsolNode.getChildNodeTags(comsolNode);
childNodes = cell(1, numel(tags));
for idxNode = 1:numel(tags)
childNodes{idxNode} = comsolNode.feature(tags(idxNode));
end
end
function childNodes = getFeatureNodesByType(comsolNode, type)
assert(ismethod(comsolNode, 'feature'), 'Given Comsol node does not have features')
tags = itaComsolNode.getChildNodeTags(comsolNode);
childNodes = {};
for idxTag = 1:numel(tags)
node = comsolNode.feature(tags(idxTag));
if strcmp(node.getType, type)
childNodes{end+1} = node;
end
end
end
......@@ -181,19 +227,7 @@ classdef (Abstract)itaComsolNode < handle
bool = true;
end
function [bool] = hasChildNode(comsolNode, childTag)
itaComsolNode.checkInputForComsolNode(comsolNode);
bool = false;
if ~ismethod(comsolNode, 'tags'); return; end
tags = cell(comsolNode.tags);
idxTag = strcmp(tags, childTag);
if sum(idxTag) ~=1; return; end
bool = true;
end
%% Properties
function setNodeProperties(comsolNode, propertyStruct)
itaComsolNode.checkInputForComsolNode(comsolNode);
......
......@@ -48,7 +48,7 @@ classdef itaComsolPhysics < itaComsolNode
%Note: This assumes that the first child of the physics node is
%always the acoustic model node
physics = obj.activeNode;
physicsFeatures = obj.getChildNodes(physics);
physicsFeatures = obj.getFeatureNodes(physics);
acousticModelNode = [];
if ~isempty(physicsFeatures)
......@@ -61,7 +61,7 @@ classdef itaComsolPhysics < itaComsolNode
methods
function impedanceNodes = ImpedanceNodes(obj)
%Returns the impedance nodes of the active physics node.
impedanceNodes = obj.getChildNodesByType(obj.mActiveNode, 'Impedance');
impedanceNodes = obj.getFeatureNodesByType(obj.mActiveNode, 'Impedance');
end
function impedanceNodeOfBoundary = ImpedanceNodeByBoundaryGroupName(obj, boundaryGroupName)
%Returns the impedance node of the active physics node that is
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment