[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  %=======================================================================


[1061]  19  % Copyright 20082019, LEGI UMR 5519 / CNRS UGA GINP, Grenoble, France


[809]  20  % http://www.legi.grenobleinp.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 

