source: trunk/src/sub_field.m @ 1086

Last change on this file since 1086 was 1071, checked in by g7moreau, 4 years ago
  • Update COPYRIGHT
File size: 11.4 KB
RevLine 
[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%=======================================================================
[1071]19% Copyright 2008-2020, 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]36function SubData=sub_field(Field,XmlData,Field_1)
[405]37
[515]38SubData=[];
39if strcmp(Field,'*')
40    return
41end
42if nargin<3
43    SubData=Field;
44    return
45end
[876]46if ~isfield(Field_1,'VarAttribute')
47    Field_1.VarAttribute={};
48end
[674]49
[405]50%% global attributes
[515]51SubData.ListGlobalAttribute={};%default
52%transfer global attributes of Field
[8]53if 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
59end
[515]60%transfer global attributes of Field_1
[8]61if 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
73end
[405]74
75%% variables
[515]76%reproduce variables of the first field and list its dimensions
[8]77SubData.ListVarName=Field.ListVarName;
78SubData.VarDimName=Field.VarDimName;
79if isfield(Field,'VarAttribute')
80    SubData.VarAttribute=Field.VarAttribute;
81end
[515]82ListDimName={};
83for 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]96end
97
[515]98%% field request
[581]99ProjModeRequest=cell(size(Field.ListVarName));
[906]100if 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
106end
[581]107ProjModeRequest_1=cell(size(Field_1.ListVarName));
[906]108if isfield(Field_1,'VarAttribute')
[515]109for 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
113end
[906]114end
[8]115
[515]116%% rename the dimensions of the second field if identical to those of the first
117for 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]131end
132
[580]133%% look for coordinates common to Field in Field_1
[866]134ind_remove=false(size(Field_1.ListVarName));
[674]135% loop on the variables of the second field Field_1
[876]136for 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
155end
[866]156if ~isempty(find(ind_remove, 1))
157Field_1.ListVarName(ind_remove)=[];%removes the redondent coordinate
158Field_1.VarDimName(ind_remove)=[];
159Field_1.VarAttribute(ind_remove)=[];
160end
[8]161
[580]162%% append the other variables of the second field, modifying their name if needed
[866]163ListVarNameSub=Field_1.ListVarName;
164ListVarNameNew=ListVarNameSub;
165check_rename=zeros(size(ListVarNameSub));
166check_remove=zeros(size(ListVarNameSub));
[985]167VarDimNameSub=Field_1.VarDimName;
[906]168VarAttributeSub={};
169if 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]192end
[866]193% apply the variable renaming and mark the second field variables with the attribute .CheckSub
194for 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]206end
207
[866]208SubData.ListVarName=[SubData.ListVarName ListVarNameNew];
209SubData.VarDimName=[SubData.VarDimName VarDimNameSub];
210SubData.VarAttribute=[SubData.VarAttribute VarAttributeSub];
211
[515]212%% substrat fields when possible
[580]213[CellInfo,NbDim,errormsg]=find_field_cells(SubData);
[866]214ind_remove=false(size(SubData.ListVarName));
[515]215ivar=[];
216ivar_1=[];
[548]217for 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
244end
[866]245% subtract fields if relevant
[515]246for 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;
251end
[866]252SubData.ListVarName(ind_remove)=[];
253SubData.VarDimName(ind_remove)=[];
254SubData.VarAttribute(ind_remove)=[];
[520]255
[580]256function OutputCell=regexprep_r(InputCell,search_string,new_string)
[713]257if ischar(InputCell); InputCell={InputCell}; end
[674]258OutputCell=InputCell;%default
[520]259for icell=1:numel(InputCell)
[580]260    OutputCell{icell}=regexprep(InputCell{icell},search_string,new_string);
[520]261end
[515]262       
263   
Note: See TracBrowser for help on using the repository browser.