[179] | 1 | %'sub_field': combines two input fields
|
---|
| 2 | %
|
---|
| 3 | % the two fields are subtstracted when of the same nature (scalar or
|
---|
| 4 | % vector), if the coordinates do not coincide, the second field is
|
---|
| 5 | % interpolated on the cooridintes of the first one
|
---|
| 6 | %
|
---|
| 7 | % when scalar and vectors are combined, the fields are just merged in a single matlab structure for common visualisation
|
---|
[8] | 8 | %-----------------------------------------------------------------------
|
---|
[515] | 9 | % function SubData=sub_field(Field,XmlData,Field_1)
|
---|
[8] | 10 | %
|
---|
[811] | 11 | % OUTPUT:
|
---|
[8] | 12 | % SubData: structure representing the resulting field
|
---|
| 13 | %
|
---|
| 14 | % INPUT:
|
---|
[179] | 15 | % Field: matlab structure representing the first field
|
---|
| 16 | % Field_1:matlab structure representing the second field
|
---|
[8] | 17 |
|
---|
[809] | 18 | %=======================================================================
|
---|
[1107] | 19 | % Copyright 2008-2022, LEGI UMR 5519 / CNRS UGA G-INP, Grenoble, France
|
---|
[809] | 20 | % http://www.legi.grenoble-inp.fr
|
---|
| 21 | % Joel.Sommeria - Joel.Sommeria (A) legi.cnrs.fr
|
---|
| 22 | %
|
---|
| 23 | % This file is part of the toolbox UVMAT.
|
---|
| 24 | %
|
---|
| 25 | % UVMAT is free software; you can redistribute it and/or modify
|
---|
| 26 | % it under the terms of the GNU General Public License as published
|
---|
| 27 | % by the Free Software Foundation; either version 2 of the license,
|
---|
| 28 | % or (at your option) any later version.
|
---|
| 29 | %
|
---|
| 30 | % UVMAT is distributed in the hope that it will be useful,
|
---|
| 31 | % but WITHOUT ANY WARRANTY; without even the implied warranty of
|
---|
| 32 | % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
---|
| 33 | % GNU General Public License (see LICENSE.txt) for more details.
|
---|
| 34 | %=======================================================================
|
---|
| 35 |
|
---|
[515] | 36 | function SubData=sub_field(Field,XmlData,Field_1)
|
---|
[405] | 37 |
|
---|
[515] | 38 | SubData=[];
|
---|
| 39 | if strcmp(Field,'*')
|
---|
| 40 | return
|
---|
| 41 | end
|
---|
| 42 | if nargin<3
|
---|
| 43 | SubData=Field;
|
---|
| 44 | return
|
---|
| 45 | end
|
---|
[876] | 46 | if ~isfield(Field_1,'VarAttribute')
|
---|
| 47 | Field_1.VarAttribute={};
|
---|
| 48 | end
|
---|
[674] | 49 |
|
---|
[405] | 50 | %% global attributes
|
---|
[515] | 51 | SubData.ListGlobalAttribute={};%default
|
---|
| 52 | %transfer global attributes of Field
|
---|
[8] | 53 | if isfield(Field,'ListGlobalAttribute')
|
---|
| 54 | SubData.ListGlobalAttribute=Field.ListGlobalAttribute;
|
---|
| 55 | for ilist=1:numel(Field.ListGlobalAttribute)
|
---|
| 56 | AttrName=Field.ListGlobalAttribute{ilist};
|
---|
[405] | 57 | SubData.(AttrName)=Field.(AttrName);
|
---|
[8] | 58 | end
|
---|
| 59 | end
|
---|
[515] | 60 | %transfer global attributes of Field_1
|
---|
[8] | 61 | if isfield(Field_1,'ListGlobalAttribute')
|
---|
| 62 | for ilist=1:numel(Field_1.ListGlobalAttribute)
|
---|
| 63 | AttrName=Field_1.ListGlobalAttribute{ilist};
|
---|
[515] | 64 | AttrNameNew=AttrName;
|
---|
| 65 | while ~isempty(find(strcmp(AttrNameNew,SubData.ListGlobalAttribute)))&&~isequal(Field_1.(AttrNameNew),Field.(AttrNameNew))
|
---|
| 66 | AttrNameNew=[AttrNameNew '_1'];
|
---|
[8] | 67 | end
|
---|
[515] | 68 | if ~isfield(Field,AttrName) || ~isequal(Field_1.(AttrName),Field.(AttrName))
|
---|
[548] | 69 | SubData.ListGlobalAttribute=[SubData.ListGlobalAttribute {AttrNameNew}];
|
---|
| 70 | SubData.(AttrNameNew)=Field_1.(AttrName);
|
---|
[8] | 71 | end
|
---|
| 72 | end
|
---|
| 73 | end
|
---|
[405] | 74 |
|
---|
| 75 | %% variables
|
---|
[515] | 76 | %reproduce variables of the first field and list its dimensions
|
---|
[8] | 77 | SubData.ListVarName=Field.ListVarName;
|
---|
| 78 | SubData.VarDimName=Field.VarDimName;
|
---|
| 79 | if isfield(Field,'VarAttribute')
|
---|
| 80 | SubData.VarAttribute=Field.VarAttribute;
|
---|
| 81 | end
|
---|
[515] | 82 | ListDimName={};
|
---|
| 83 | for ilist=1:numel(Field.ListVarName)
|
---|
| 84 | VarName=Field.ListVarName{ilist};
|
---|
| 85 | SubData.(VarName)=Field.(VarName);
|
---|
| 86 | SubData.VarAttribute{ilist}.CheckSub=0;
|
---|
| 87 | DimCell=Field.VarDimName{ilist};
|
---|
| 88 | if ischar(DimCell)
|
---|
| 89 | DimCell={DimCell};
|
---|
| 90 | end
|
---|
| 91 | for idim=1:numel(DimCell)
|
---|
| 92 | if isempty(find(strcmp(DimCell{idim},ListDimName)))
|
---|
| 93 | ListDimName=[ListDimName DimCell(idim)];
|
---|
| 94 | end
|
---|
| 95 | end
|
---|
[8] | 96 | end
|
---|
| 97 |
|
---|
[515] | 98 | %% field request
|
---|
[581] | 99 | ProjModeRequest=cell(size(Field.ListVarName));
|
---|
[906] | 100 | if isfield(Field,'VarAttribute')
|
---|
[1033] | 101 | for ilist=1:numel(Field.VarAttribute)
|
---|
| 102 | if isfield(Field.VarAttribute{ilist},'ProjModeRequest')
|
---|
| 103 | ProjModeRequest{ilist}=Field.VarAttribute{ilist}.ProjModeRequest;
|
---|
| 104 | end
|
---|
[402] | 105 | end
|
---|
| 106 | end
|
---|
[581] | 107 | ProjModeRequest_1=cell(size(Field_1.ListVarName));
|
---|
[906] | 108 | if isfield(Field_1,'VarAttribute')
|
---|
[515] | 109 | for ilist=1:numel(Field_1.VarAttribute)
|
---|
[581] | 110 | if isfield(Field_1.VarAttribute{ilist},'ProjModeRequest')
|
---|
| 111 | ProjModeRequest_1{ilist}=Field_1.VarAttribute{ilist}.ProjModeRequest;
|
---|
[402] | 112 | end
|
---|
| 113 | end
|
---|
[906] | 114 | end
|
---|
[8] | 115 |
|
---|
[515] | 116 | %% rename the dimensions of the second field if identical to those of the first
|
---|
| 117 | for ilist=1:numel(Field_1.VarDimName)
|
---|
| 118 | DimCell=Field_1.VarDimName{ilist};
|
---|
| 119 | if ischar(DimCell)
|
---|
| 120 | DimCell={DimCell};
|
---|
| 121 | end
|
---|
| 122 | for idim=1:numel(DimCell)
|
---|
| 123 | ind_dim=find(strcmp(DimCell{idim},ListDimName));
|
---|
| 124 | if ~isempty(ind_dim)
|
---|
| 125 | if ischar(Field_1.VarDimName{ilist})
|
---|
| 126 | Field_1.VarDimName{ilist}=Field_1.VarDimName(ilist);
|
---|
| 127 | end
|
---|
| 128 | Field_1.VarDimName{ilist}{idim}=[ListDimName{ind_dim} '_1'];
|
---|
| 129 | end
|
---|
| 130 | end
|
---|
[8] | 131 | end
|
---|
| 132 |
|
---|
[580] | 133 | %% look for coordinates common to Field in Field_1
|
---|
[866] | 134 | ind_remove=false(size(Field_1.ListVarName));
|
---|
[674] | 135 | % loop on the variables of the second field Field_1
|
---|
[876] | 136 | for ilist=1:numel(Field_1.VarAttribute)
|
---|
[674] | 137 | % case of variable with a single dimension
|
---|
[1024] | 138 | if ~isempty(Field_1.VarAttribute{ilist}) && isfield(Field_1.VarAttribute{ilist},'Role')&&~isempty(regexp(Field_1.VarAttribute{ilist}.Role,'^coord'))% if variable with Role coord... is found.
|
---|
[864] | 139 | OldDimName=Field_1.VarDimName{ilist};
|
---|
| 140 | if ischar(OldDimName), OldDimName={OldDimName}; end% transform char string to cell if relevant
|
---|
| 141 | if numel(OldDimName)==1
|
---|
| 142 | OldDim=Field_1.(Field_1.ListVarName{ilist});% get variable
|
---|
| 143 | %look for the existence of the variable OldDim in the first field Field
|
---|
| 144 | for i1=1:numel(Field.ListVarName)
|
---|
| 145 | if isequal(Field.(Field.ListVarName{i1}),OldDim) &&...
|
---|
| 146 | ((isempty(ProjModeRequest{i1}) && isempty(ProjModeRequest_1{ilist})) || strcmp(ProjModeRequest{i1},ProjModeRequest_1{ilist}))
|
---|
| 147 | ind_remove(ilist)=1;
|
---|
| 148 | NewDimName=Field.VarDimName{i1};
|
---|
| 149 | if ischar(NewDimName), NewDimName={NewDimName}; end %transform char chain to cell if needed
|
---|
| 150 | Field_1.VarDimName=regexprep_r(Field_1.VarDimName,['^' OldDimName{1} '$'],NewDimName{1});% change the var name of Field_1 to the corresponding var name of Field
|
---|
| 151 | end
|
---|
[180] | 152 | end
|
---|
| 153 | end
|
---|
[8] | 154 | end
|
---|
| 155 | end
|
---|
[866] | 156 | if ~isempty(find(ind_remove, 1))
|
---|
| 157 | Field_1.ListVarName(ind_remove)=[];%removes the redondent coordinate
|
---|
| 158 | Field_1.VarDimName(ind_remove)=[];
|
---|
| 159 | Field_1.VarAttribute(ind_remove)=[];
|
---|
| 160 | end
|
---|
[8] | 161 |
|
---|
[580] | 162 | %% append the other variables of the second field, modifying their name if needed
|
---|
[866] | 163 | ListVarNameSub=Field_1.ListVarName;
|
---|
| 164 | ListVarNameNew=ListVarNameSub;
|
---|
| 165 | check_rename=zeros(size(ListVarNameSub));
|
---|
| 166 | check_remove=zeros(size(ListVarNameSub));
|
---|
[985] | 167 | VarDimNameSub=Field_1.VarDimName;
|
---|
[906] | 168 | VarAttributeSub={};
|
---|
| 169 | if isfield(Field_1,'VarAttribute')&&~isempty(Field_1.VarAttribute)
|
---|
| 170 | for ilist=1:numel(ListVarNameSub)
|
---|
| 171 | ind_prev=find(strcmp(ListVarNameSub{ilist},Field.ListVarName),1);% look for duplicated variable name
|
---|
| 172 | if ~isempty(ind_prev)% variable name exists in Field
|
---|
| 173 | if isfield(Field_1.VarAttribute{ilist},'Role')&&...
|
---|
| 174 | ismember(Field_1.VarAttribute{ilist}.Role,{'coord_x','coord_y','scalar','vector_x','vector_y','errorflag'})
|
---|
| 175 | ListVarNameNew{ilist}=[ListVarNameSub{ilist} '_1'];%modify the name of the second variable
|
---|
| 176 | check_rename(ilist)=1;
|
---|
| 177 | else
|
---|
| 178 | check_remove(ilist)=1;% variable will be removed
|
---|
| 179 | end
|
---|
[864] | 180 | end
|
---|
[8] | 181 | end
|
---|
[906] | 182 | ListVarNameSub=ListVarNameSub(~check_remove); %eliminate removed variables from the list of the second field
|
---|
| 183 | ListVarNameNew=ListVarNameNew(~check_remove); % %list of renaimed varaibles corresponding to ListVarNameSub
|
---|
| 184 | VarDimNameSub=Field_1.VarDimName(~check_remove);
|
---|
| 185 | if numel(Field_1.VarAttribute)<max(find(~check_remove))
|
---|
| 186 | for ilist=numel(Field_1.VarAttribute)+1:max(find(~check_remove))
|
---|
| 187 | Field_1.VarAttribute{ilist}={};
|
---|
| 188 | end
|
---|
[876] | 189 | end
|
---|
[906] | 190 | VarAttributeSub=Field_1.VarAttribute(~check_remove);
|
---|
| 191 | check_rename=check_rename(~check_remove);
|
---|
[876] | 192 | end
|
---|
[866] | 193 | % apply the variable renaming and mark the second field variables with the attribute .CheckSub
|
---|
| 194 | for ilist=1:numel(ListVarNameSub)
|
---|
| 195 | SubData.(ListVarNameNew{ilist})=Field_1.(ListVarNameSub{ilist});% copy the variable content to the new name
|
---|
| 196 | if check_rename(ilist)
|
---|
| 197 | % replace name in field expression FieldName, e.g. 'norm(U,V)'-> 'norm(U_1,V_1)'
|
---|
| 198 | if isfield(VarAttributeSub{ilist},'FieldName')
|
---|
| 199 | for ivar=1:numel(find(check_rename))
|
---|
| 200 | VarAttributeSub{ilist}.FieldName=regexprep_r(VarAttributeSub{ilist}.FieldName,...
|
---|
| 201 | ListVarNameSub{ivar},ListVarNameNew{ivar});
|
---|
| 202 | end
|
---|
[862] | 203 | end
|
---|
| 204 | end
|
---|
[866] | 205 | VarAttributeSub{ilist}.CheckSub=1;% mark that the field needs to be substracted as an attribute
|
---|
[862] | 206 | end
|
---|
| 207 |
|
---|
[866] | 208 | SubData.ListVarName=[SubData.ListVarName ListVarNameNew];
|
---|
| 209 | SubData.VarDimName=[SubData.VarDimName VarDimNameSub];
|
---|
| 210 | SubData.VarAttribute=[SubData.VarAttribute VarAttributeSub];
|
---|
| 211 |
|
---|
[515] | 212 | %% substrat fields when possible
|
---|
[580] | 213 | [CellInfo,NbDim,errormsg]=find_field_cells(SubData);
|
---|
[866] | 214 | ind_remove=false(size(SubData.ListVarName));
|
---|
[515] | 215 | ivar=[];
|
---|
| 216 | ivar_1=[];
|
---|
[548] | 217 | for icell=1:numel(CellInfo)
|
---|
| 218 | if ~isempty(CellInfo{icell})
|
---|
[866] | 219 | % if two scalar are in the same cell
|
---|
[548] | 220 | if isfield(CellInfo{icell},'VarIndex_scalar') && numel(CellInfo{icell}.VarIndex_scalar)==2 && SubData.VarAttribute{CellInfo{icell}.VarIndex_scalar(2)}.CheckSub;
|
---|
| 221 | ivar=[ivar CellInfo{icell}.VarIndex_scalar(1)];
|
---|
| 222 | ivar_1=[ivar_1 CellInfo{icell}.VarIndex_scalar(2)];
|
---|
[8] | 223 | end
|
---|
[866] | 224 | % if two vector u components are in the same cell
|
---|
[548] | 225 | if isfield(CellInfo{icell},'VarIndex_vector_x') && numel(CellInfo{icell}.VarIndex_vector_x)==2 && SubData.VarAttribute{CellInfo{icell}.VarIndex_vector_x(2)}.CheckSub;
|
---|
| 226 | ivar=[ivar CellInfo{icell}.VarIndex_vector_x(1)];
|
---|
| 227 | ivar_1=[ivar_1 CellInfo{icell}.VarIndex_vector_x(2)];
|
---|
[515] | 228 | end
|
---|
[866] | 229 | % if two vector v components are in the same cell
|
---|
[548] | 230 | if isfield(CellInfo{icell},'VarIndex_vector_y') && numel(CellInfo{icell}.VarIndex_vector_y)==2 && SubData.VarAttribute{CellInfo{icell}.VarIndex_vector_y(2)}.CheckSub;
|
---|
| 231 | ivar=[ivar CellInfo{icell}.VarIndex_vector_y(1)];
|
---|
| 232 | ivar_1=[ivar_1 CellInfo{icell}.VarIndex_vector_y(2)];
|
---|
[515] | 233 | end
|
---|
[866] | 234 | % merge the error flags if needed
|
---|
| 235 | if isfield(CellInfo{icell},'VarIndex_errorflag') && numel(CellInfo{icell}.VarIndex_errorflag)==2 && SubData.VarAttribute{CellInfo{icell}.VarIndex_vector_y(2)}.CheckSub;
|
---|
| 236 | ivar_flag=CellInfo{icell}.VarIndex_errorflag(1);
|
---|
| 237 | ivar_flag_1=CellInfo{icell}.VarIndex_errorflag(2);
|
---|
| 238 | VarName=SubData.ListVarName{ivar_flag};
|
---|
| 239 | VarName_1=SubData.ListVarName{ivar_flag_1};
|
---|
| 240 | SubData.(VarName)=SubData.(VarName)~=0 | SubData.(VarName_1)~=0;% combine the error flags of the two fields
|
---|
| 241 | ind_remove(ivar_flag_1)=1;
|
---|
| 242 | end
|
---|
[8] | 243 | end
|
---|
| 244 | end
|
---|
[866] | 245 | % subtract fields if relevant
|
---|
[515] | 246 | for imod=1:numel(ivar)
|
---|
| 247 | VarName=SubData.ListVarName{ivar(imod)};
|
---|
| 248 | VarName_1=SubData.ListVarName{ivar_1(imod)};
|
---|
[548] | 249 | SubData.(VarName)=double(SubData.(VarName))-double(SubData.(VarName_1));
|
---|
[515] | 250 | ind_remove(ivar_1(imod))=1;
|
---|
| 251 | end
|
---|
[866] | 252 | SubData.ListVarName(ind_remove)=[];
|
---|
| 253 | SubData.VarDimName(ind_remove)=[];
|
---|
| 254 | SubData.VarAttribute(ind_remove)=[];
|
---|
[520] | 255 |
|
---|
[580] | 256 | function OutputCell=regexprep_r(InputCell,search_string,new_string)
|
---|
[713] | 257 | if ischar(InputCell); InputCell={InputCell}; end
|
---|
[674] | 258 | OutputCell=InputCell;%default
|
---|
[520] | 259 | for icell=1:numel(InputCell)
|
---|
[580] | 260 | OutputCell{icell}=regexprep(InputCell{icell},search_string,new_string);
|
---|
[520] | 261 | end
|
---|
[515] | 262 |
|
---|
| 263 |
|
---|