Ignore:
Timestamp:
08/20/12 17:39:30 (13 years ago)
Author:
cborstad
Message:

merged trunk-jpl through revision 13099 into branch

Location:
issm/branches/trunk-jpl-damage
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • issm/branches/trunk-jpl-damage

    • Property svn:ignore
      •  

        old new  
         1projects
        12autom4te.cache
        23aclocal.m4
    • Property svn:mergeinfo changed
      /issm/trunk-jplmerged: 12948-13099
  • issm/branches/trunk-jpl-damage/src/m/classes/model/model.m

    r12878 r13101  
    9191                 end
    9292                 %}}}
     93                 function md = collapse(md)% {{{
     94                         %COLLAPSE - collapses a 3d mesh into a 2d mesh
     95                         %
     96                         %   This routine collapses a 3d model into a 2d model
     97                         %   and collapses all the fileds of the 3d model by
     98                         %   taking their depth-averaged values
     99                         %
     100                         %   Usage:
     101                         %      md=collapse(md)
     102                         %
     103                         %   See also: EXTRUDE, MODELEXTRACT
     104
     105                         %Check that the model is really a 3d model
     106                         if ~md.mesh.dimension==3,
     107                                 error('collapse error message: only 3d mesh can be collapsed')
     108                         end
     109
     110                         %Start with changing alle the fields from the 3d mesh
     111
     112                         %drag is limited to nodes that are on the bedrock.
     113                         md.friction.coefficient=project2d(md,md.friction.coefficient,1);
     114
     115                         %p and q (same deal, except for element that are on the bedrock: )
     116                         md.friction.p=project2d(md,md.friction.p,1);
     117                         md.friction.q=project2d(md,md.friction.q,1);
     118
     119                         %observations
     120                         if ~isnan(md.inversion.vx_obs), md.inversion.vx_obs=project2d(md,md.inversion.vx_obs,md.mesh.numberoflayers); end;
     121                         if ~isnan(md.inversion.vy_obs), md.inversion.vy_obs=project2d(md,md.inversion.vy_obs,md.mesh.numberoflayers); end;
     122                         if ~isnan(md.inversion.vel_obs), md.inversion.vel_obs=project2d(md,md.inversion.vel_obs,md.mesh.numberoflayers); end;
     123                         if ~isnan(md.inversion.cost_functions_coefficients), md.inversion.cost_functions_coefficients=project2d(md,md.inversion.cost_functions_coefficients,md.mesh.numberoflayers); end;
     124                         if numel(md.inversion.min_parameters)>1, md.inversion.min_parameters=project2d(md,md.inversion.min_parameters,md.mesh.numberoflayers); end;
     125                         if numel(md.inversion.max_parameters)>1, md.inversion.max_parameters=project2d(md,md.inversion.max_parameters,md.mesh.numberoflayers); end;
     126                         if ~isnan(md.surfaceforcings.mass_balance),
     127                                 md.surfaceforcings.mass_balance=project2d(md,md.surfaceforcings.mass_balance,md.mesh.numberoflayers);
     128                         end;
     129                         if ~isnan(md.balancethickness.thickening_rate), md.balancethickness.thickening_rate=project2d(md,md.balancethickness.thickening_rate,md.mesh.numberoflayers); end;
     130
     131                         %results
     132                         if ~isnan(md.initialization.vx),md.initialization.vx=DepthAverage(md,md.initialization.vx);end;
     133                         if ~isnan(md.initialization.vy),md.initialization.vy=DepthAverage(md,md.initialization.vy);end;
     134                         if ~isnan(md.initialization.vz),md.initialization.vz=DepthAverage(md,md.initialization.vz);end;
     135                         if ~isnan(md.initialization.vel),md.initialization.vel=DepthAverage(md,md.initialization.vel);end;
     136                         if ~isnan(md.initialization.temperature),md.initialization.temperature=DepthAverage(md,md.initialization.temperature);end;
     137
     138                         %bedinfo and surface info
     139                         md.mesh.elementonbed=ones(md.mesh.numberofelements2d,1);
     140                         md.mesh.elementonsurface=ones(md.mesh.numberofelements2d,1);
     141                         md.mesh.vertexonbed=ones(md.mesh.numberofvertices2d,1);
     142                         md.mesh.vertexonsurface=ones(md.mesh.numberofvertices2d,1);
     143
     144                         %elementstype
     145                         if ~isnan(md.flowequation.element_equation)
     146                                 md.flowequation.element_equation=project2d(md,md.flowequation.element_equation,1);
     147                                 md.flowequation.vertex_equation=project2d(md,md.flowequation.vertex_equation,1);
     148                                 md.flowequation.bordermacayeal=project2d(md,md.flowequation.bordermacayeal,1);
     149                                 md.flowequation.borderpattyn=project2d(md,md.flowequation.borderpattyn,1);
     150                                 md.flowequation.borderstokes=project2d(md,md.flowequation.borderstokes,1);
     151                         end   
     152
     153                         %boundary conditions
     154                         md.diagnostic.spcvx=project2d(md,md.diagnostic.spcvx,md.mesh.numberoflayers);
     155                         md.diagnostic.spcvy=project2d(md,md.diagnostic.spcvy,md.mesh.numberoflayers);
     156                         md.diagnostic.spcvz=project2d(md,md.diagnostic.spcvz,md.mesh.numberoflayers);
     157                         md.diagnostic.referential=project2d(md,md.diagnostic.referential,md.mesh.numberoflayers);
     158                         md.prognostic.spcthickness=project2d(md,md.prognostic.spcthickness,md.mesh.numberoflayers);
     159                         md.thermal.spctemperature=project2d(md,md.thermal.spctemperature,md.mesh.numberoflayers);
     160
     161                         %Extrusion of Neumann BC
     162                         if ~isnan(md.diagnostic.icefront),
     163                                 numberofneumann2d=size(md.diagnostic.icefront,1)/(md.mesh.numberoflayers-1);
     164                                 md.diagnostic.icefront=[md.diagnostic.icefront(1:numberofneumann2d,1:2) md.diagnostic.icefront(1:numberofneumann2d,5:6)]; %Add two columns on the first layer
     165                         end
     166
     167                         %materials
     168                         md.materials.rheology_B=DepthAverage(md,md.materials.rheology_B);
     169                         md.materials.rheology_n=project2d(md,md.materials.rheology_n,1);
     170
     171                         %special for thermal modeling:
     172                         md.basalforcings.melting_rate=project2d(md,md.basalforcings.melting_rate,1);
     173                         md.basalforcings.geothermalflux=project2d(md,md.basalforcings.geothermalflux,1); %bedrock only gets geothermal flux
     174
     175                         %update of connectivity matrix
     176                         md.mesh.average_vertex_connectivity=25;
     177
     178                         %Collapse the mesh
     179                         nodes2d=md.mesh.numberofvertices2d;
     180                         elements2d=md.mesh.numberofelements2d;
     181
     182                         %parameters
     183                         md.geometry.surface=project2d(md,md.geometry.surface,1);
     184                         md.geometry.thickness=project2d(md,md.geometry.thickness,1);
     185                         md.geometry.bed=project2d(md,md.geometry.bed,1);
     186                         md.geometry.bathymetry=project2d(md,md.geometry.bathymetry,1);
     187                         md.mesh.vertexonboundary=project2d(md,md.mesh.vertexonboundary,1);
     188                         md.mesh.elementconnectivity=project2d(md,md.mesh.elementconnectivity,1);
     189                         md.mask.elementonfloatingice=project2d(md,md.mask.elementonfloatingice,1);
     190                         md.mask.vertexonfloatingice=project2d(md,md.mask.vertexonfloatingice,1);
     191                         md.mask.elementongroundedice=project2d(md,md.mask.elementongroundedice,1);
     192                         md.mask.vertexongroundedice=project2d(md,md.mask.vertexongroundedice,1);
     193                         md.mask.elementonwater=project2d(md,md.mask.elementonwater,1);
     194                         md.mask.vertexonwater=project2d(md,md.mask.vertexonwater,1);
     195
     196                         %lat long
     197                         if numel(md.mesh.lat) ==md.mesh.numberofvertices,  md.mesh.lat=project2d(md,md.mesh.lat,1); end
     198                         if numel(md.mesh.long)==md.mesh.numberofvertices, md.mesh.long=project2d(md,md.mesh.long,1); end
     199
     200                         %Initialize with the 2d mesh
     201                         md.mesh.x=md.mesh.x2d;
     202                         md.mesh.y=md.mesh.y2d;
     203                         md.mesh.z=zeros(size(md.mesh.x2d));
     204                         md.mesh.numberofvertices=md.mesh.numberofvertices2d;
     205                         md.mesh.numberofelements=md.mesh.numberofelements2d;
     206                         md.mesh.elements=md.mesh.elements2d;
     207
     208                         %Keep a trace of lower and upper nodes
     209                         md.mesh.lowervertex=NaN;
     210                         md.mesh.uppervertex=NaN;
     211                         md.mesh.lowerelements=NaN;
     212                         md.mesh.upperelements=NaN;
     213
     214                         %Remove old mesh
     215                         md.mesh.x2d=NaN;
     216                         md.mesh.y2d=NaN;
     217                         md.mesh.elements2d=NaN;
     218                         md.mesh.numberofelements2d=md.mesh.numberofelements;
     219                         md.mesh.numberofvertices2d=md.mesh.numberofvertices;
     220                         md.mesh.numberoflayers=0;
     221
     222                         %Update mesh type
     223                         md.mesh.dimension=2;
     224                 end % }}}
     225                 function md2 = extract(md,area) % {{{
     226                         %extract - extract a model according to an Argus contour or flag list
     227                         %
     228                         %   This routine extracts a submodel from a bigger model with respect to a given contour
     229                         %   md must be followed by the corresponding exp file or flags list
     230                         %   It can either be a domain file (argus type, .exp extension), or an array of element flags.
     231                         %   If user wants every element outside the domain to be
     232                         %   extract2d, add '~' to the name of the domain file (ex: '~Pattyn.exp');
     233                         %   an empty string '' will be considered as an empty domain
     234                         %   a string 'all' will be considered as the entire domain
     235                         %   add an argument 0 if you do not want the elements to be checked (faster)
     236                         %
     237                         %   Usage:
     238                         %      md2=extract(md,area);
     239                         %
     240                         %   Examples:
     241                         %      md2=extract(md,'Domain.exp');
     242                         %      md2=extract(md,md.mask.elementonfloatingice);
     243                         %
     244                         %   See also: EXTRUDE, COLLAPSE
     245
     246                         %copy model
     247                         md1=md;
     248
     249                         %some checks
     250                         if ((nargin~=2) | (nargout~=1)),
     251                                 help extract
     252                                 error('extract error message: bad usage');
     253                         end
     254
     255                         %get check option
     256                         if (nargin==3 & varargin{1}==0),
     257                                 checkoutline=0;
     258                         else
     259                                 checkoutline=1;
     260                         end
     261
     262                         %get elements that are inside area
     263                         flag_elem=FlagElements(md1,area);
     264                         if ~any(flag_elem),
     265                                 error('extracted model is empty');
     266                         end
     267
     268                         %kick out all elements with 3 dirichlets
     269                         spc_elem=find(~flag_elem);
     270                         spc_node=sort(unique(md1.mesh.elements(spc_elem,:)));
     271                         flag=ones(md1.mesh.numberofvertices,1);
     272                         flag(spc_node)=0;
     273                         pos=find(sum(flag(md1.mesh.elements),2)==0);
     274                         flag_elem(pos)=0;
     275
     276                         %extracted elements and nodes lists
     277                         pos_elem=find(flag_elem);
     278                         pos_node=sort(unique(md1.mesh.elements(pos_elem,:)));
     279
     280                         %keep track of some fields
     281                         numberofvertices1=md1.mesh.numberofvertices;
     282                         numberofelements1=md1.mesh.numberofelements;
     283                         numberofvertices2=length(pos_node);
     284                         numberofelements2=length(pos_elem);
     285                         flag_node=zeros(numberofvertices1,1);
     286                         flag_node(pos_node)=1;
     287
     288                         %Create Pelem and Pnode (transform old nodes in new nodes and same thing for the elements)
     289                         Pelem=zeros(numberofelements1,1);
     290                         Pelem(pos_elem)=[1:numberofelements2]';
     291                         Pnode=zeros(numberofvertices1,1);
     292                         Pnode(pos_node)=[1:numberofvertices2]';
     293
     294                         %renumber the elements (some node won't exist anymore)
     295                         elements_1=md1.mesh.elements;
     296                         elements_2=elements_1(pos_elem,:);
     297                         elements_2(:,1)=Pnode(elements_2(:,1));
     298                         elements_2(:,2)=Pnode(elements_2(:,2));
     299                         elements_2(:,3)=Pnode(elements_2(:,3));
     300                         if md1.mesh.dimension==3,
     301                                 elements_2(:,4)=Pnode(elements_2(:,4));
     302                                 elements_2(:,5)=Pnode(elements_2(:,5));
     303                                 elements_2(:,6)=Pnode(elements_2(:,6));
     304                         end
     305
     306                         %OK, now create the new model !
     307
     308                         %take every fields from model
     309                         md2=md1;
     310
     311                         %automatically modify fields
     312
     313                         %loop over model fields
     314                         model_fields=fields(md1);
     315                         for i=1:length(model_fields),
     316                                 %get field
     317                                 field=md1.(model_fields{i});
     318                                 fieldsize=size(field);
     319                                 if isobject(field), %recursive call
     320                                         object_fields=fields(md1.(model_fields{i}));
     321                                         for j=1:length(object_fields),
     322                                                 %get field
     323                                                 field=md1.(model_fields{i}).(object_fields{j});
     324                                                 fieldsize=size(field);
     325                                                 %size = number of nodes * n
     326                                                 if fieldsize(1)==numberofvertices1
     327                                                         md2.(model_fields{i}).(object_fields{j})=field(pos_node,:);
     328                                                 elseif (fieldsize(1)==numberofvertices1+1)
     329                                                         md2.(model_fields{i}).(object_fields{j})=[field(pos_node,:); field(end,:)];
     330                                                         %size = number of elements * n
     331                                                 elseif fieldsize(1)==numberofelements1
     332                                                         md2.(model_fields{i}).(object_fields{j})=field(pos_elem,:);
     333                                                 end
     334                                         end
     335                                 else
     336                                         %size = number of nodes * n
     337                                         if fieldsize(1)==numberofvertices1
     338                                                 md2.(model_fields{i})=field(pos_node,:);
     339                                         elseif (fieldsize(1)==numberofvertices1+1)
     340                                                 md2.(model_fields{i})=[field(pos_node,:); field(end,:)];
     341                                                 %size = number of elements * n
     342                                         elseif fieldsize(1)==numberofelements1
     343                                                 md2.(model_fields{i})=field(pos_elem,:);
     344                                         end
     345                                 end
     346                         end
     347
     348                         %modify some specific fields
     349
     350                         %Mesh
     351                         md2.mesh.numberofelements=numberofelements2;
     352                         md2.mesh.numberofvertices=numberofvertices2;
     353                         md2.mesh.elements=elements_2;
     354
     355                         %mesh.uppervertex mesh.lowervertex
     356                         if md1.mesh.dimension==3
     357                                 md2.mesh.uppervertex=md1.mesh.uppervertex(pos_node);
     358                                 pos=find(~isnan(md2.mesh.uppervertex));
     359                                 md2.mesh.uppervertex(pos)=Pnode(md2.mesh.uppervertex(pos));
     360
     361                                 md2.mesh.lowervertex=md1.mesh.lowervertex(pos_node);
     362                                 pos=find(~isnan(md2.mesh.lowervertex));
     363                                 md2.mesh.lowervertex(pos)=Pnode(md2.mesh.lowervertex(pos));
     364
     365                                 md2.mesh.upperelements=md1.mesh.upperelements(pos_elem);
     366                                 pos=find(~isnan(md2.mesh.upperelements));
     367                                 md2.mesh.upperelements(pos)=Pelem(md2.mesh.upperelements(pos));
     368
     369                                 md2.mesh.lowerelements=md1.mesh.lowerelements(pos_elem);
     370                                 pos=find(~isnan(md2.mesh.lowerelements));
     371                                 md2.mesh.lowerelements(pos)=Pelem(md2.mesh.lowerelements(pos));
     372                         end
     373
     374                         %Initial 2d mesh
     375                         if md1.mesh.dimension==3
     376                                 flag_elem_2d=flag_elem(1:md1.mesh.numberofelements2d);
     377                                 pos_elem_2d=find(flag_elem_2d);
     378                                 flag_node_2d=flag_node(1:md1.mesh.numberofvertices2d);
     379                                 pos_node_2d=find(flag_node_2d);
     380
     381                                 md2.mesh.numberofelements2d=length(pos_elem_2d);
     382                                 md2.mesh.numberofvertices2d=length(pos_node_2d);
     383                                 md2.mesh.elements2d=md1.mesh.elements2d(pos_elem_2d,:);
     384                                 md2.mesh.elements2d(:,1)=Pnode(md2.mesh.elements2d(:,1));
     385                                 md2.mesh.elements2d(:,2)=Pnode(md2.mesh.elements2d(:,2));
     386                                 md2.mesh.elements2d(:,3)=Pnode(md2.mesh.elements2d(:,3));
     387
     388                                 md2.mesh.x2d=md1.mesh.x(pos_node_2d);
     389                                 md2.mesh.y2d=md1.mesh.y(pos_node_2d);
     390                         end
     391
     392                         %Edges
     393                         if size(md2.mesh.edges,2)>1, %do not use ~isnan because there are some NaNs...
     394                                 %renumber first two columns
     395                                 pos=find(md2.mesh.edges(:,4)~=-1);
     396                                 md2.mesh.edges(:  ,1)=Pnode(md2.mesh.edges(:,1));
     397                                 md2.mesh.edges(:  ,2)=Pnode(md2.mesh.edges(:,2));
     398                                 md2.mesh.edges(:  ,3)=Pelem(md2.mesh.edges(:,3));
     399                                 md2.mesh.edges(pos,4)=Pelem(md2.mesh.edges(pos,4));
     400                                 %remove edges when the 2 vertices are not in the domain.
     401                                 md2.mesh.edges=md2.mesh.edges(find(md2.mesh.edges(:,1) & md2.mesh.edges(:,2)),:);
     402                                 %Replace all zeros by -1 in the last two columns;
     403                                 pos=find(md2.mesh.edges(:,3)==0);
     404                                 md2.mesh.edges(pos,3)=-1;
     405                                 pos=find(md2.mesh.edges(:,4)==0);
     406                                 md2.mesh.edges(pos,4)=-1;
     407                                 %Invert -1 on the third column with last column (Also invert first two columns!!)
     408                                 pos=find(md2.mesh.edges(:,3)==-1);
     409                                 md2.mesh.edges(pos,3)=md2.mesh.edges(pos,4);
     410                                 md2.mesh.edges(pos,4)=-1;
     411                                 values=md2.mesh.edges(pos,2);
     412                                 md2.mesh.edges(pos,2)=md2.mesh.edges(pos,1);
     413                                 md2.mesh.edges(pos,1)=values;
     414                                 %Finally remove edges that do not belong to any element
     415                                 pos=find(md2.mesh.edges(:,3)==-1 & md2.mesh.edges(:,4)==-1);
     416                                 md2.mesh.edges(pos,:)=[];
     417                         end
     418
     419                         %Penalties
     420                         if ~isnan(md2.diagnostic.vertex_pairing),
     421                                 for i=1:size(md1.diagnostic.vertex_pairing,1);
     422                                         md2.diagnostic.vertex_pairing(i,:)=Pnode(md1.diagnostic.vertex_pairing(i,:));
     423                                 end
     424                                 md2.diagnostic.vertex_pairing=md2.diagnostic.vertex_pairing(find(md2.diagnostic.vertex_pairing(:,1)),:);
     425                         end
     426                         if ~isnan(md2.prognostic.vertex_pairing),
     427                                 for i=1:size(md1.prognostic.vertex_pairing,1);
     428                                         md2.prognostic.vertex_pairing(i,:)=Pnode(md1.prognostic.vertex_pairing(i,:));
     429                                 end
     430                                 md2.prognostic.vertex_pairing=md2.prognostic.vertex_pairing(find(md2.prognostic.vertex_pairing(:,1)),:);
     431                         end
     432
     433                         %recreate segments
     434                         if md1.mesh.dimension==2
     435                                 md2.mesh.vertexconnectivity=NodeConnectivity(md2.mesh.elements,md2.mesh.numberofvertices);
     436                                 md2.mesh.elementconnectivity=ElementConnectivity(md2.mesh.elements,md2.mesh.vertexconnectivity);
     437                                 md2.mesh.segments=contourenvelope(md2);
     438                                 md2.mesh.vertexonboundary=zeros(numberofvertices2,1); md2.mesh.vertexonboundary(md2.mesh.segments(:,1:2))=1;
     439                         else
     440                                 %First do the connectivity for the contourenvelope in 2d
     441                                 md2.mesh.vertexconnectivity=NodeConnectivity(md2.mesh.elements2d,md2.mesh.numberofvertices2d);
     442                                 md2.mesh.elementconnectivity=ElementConnectivity(md2.mesh.elements2d,md2.mesh.vertexconnectivity);
     443                                 md2.mesh.segments=contourenvelope(md2);
     444                                 md2.mesh.vertexonboundary=zeros(numberofvertices2/md2.mesh.numberoflayers,1); md2.mesh.vertexonboundary(md2.mesh.segments(:,1:2))=1;
     445                                 md2.mesh.vertexonboundary=repmat(md2.mesh.vertexonboundary,md2.mesh.numberoflayers,1);
     446                                 %Then do it for 3d as usual
     447                                 md2.mesh.vertexconnectivity=NodeConnectivity(md2.mesh.elements,md2.mesh.numberofvertices);
     448                                 md2.mesh.elementconnectivity=ElementConnectivity(md2.mesh.elements,md2.mesh.vertexconnectivity);
     449                         end
     450
     451                         %Boundary conditions: Dirichlets on new boundary
     452                         %Catch the elements that have not been extracted
     453                         orphans_elem=find(~flag_elem);
     454                         orphans_node=unique(md1.mesh.elements(orphans_elem,:))';
     455                         %Figure out which node are on the boundary between md2 and md1
     456                         nodestoflag1=intersect(orphans_node,pos_node);
     457                         nodestoflag2=Pnode(nodestoflag1);
     458                         if numel(md1.diagnostic.spcvx)>1 & numel(md1.diagnostic.spcvy)>2 & numel(md1.diagnostic.spcvz)>2,
     459                                 if numel(md1.inversion.vx_obs)>1 & numel(md1.inversion.vy_obs)>1
     460                                         md2.diagnostic.spcvx(nodestoflag2)=md2.inversion.vx_obs(nodestoflag2);
     461                                         md2.diagnostic.spcvy(nodestoflag2)=md2.inversion.vy_obs(nodestoflag2);
     462                                 else
     463                                         md2.diagnostic.spcvx(nodestoflag2)=NaN;
     464                                         md2.diagnostic.spcvy(nodestoflag2)=NaN;
     465                                         disp(' ')
     466                                         disp('!! extract warning: spc values should be checked !!')
     467                                         disp(' ')
     468                                 end
     469                                 %put 0 for vz
     470                                 md2.diagnostic.spcvz(nodestoflag2)=0;
     471                         end
     472                         if ~isnan(md1.thermal.spctemperature),
     473                                 md2.thermal.spctemperature(nodestoflag2,1)=1;
     474                         end
     475
     476                         %Diagnostic
     477                         if ~isnan(md2.diagnostic.icefront)
     478                                 md2.diagnostic.icefront(:,1)=Pnode(md1.diagnostic.icefront(:,1));
     479                                 md2.diagnostic.icefront(:,2)=Pnode(md1.diagnostic.icefront(:,2));
     480                                 md2.diagnostic.icefront(:,end-1)=Pelem(md1.diagnostic.icefront(:,end-1));
     481                                 if md1.mesh.dimension==3
     482                                         md2.diagnostic.icefront(:,3)=Pnode(md1.diagnostic.icefront(:,3));
     483                                         md2.diagnostic.icefront(:,4)=Pnode(md1.diagnostic.icefront(:,4));
     484                                 end
     485                                 md2.diagnostic.icefront=md2.diagnostic.icefront(find(md2.diagnostic.icefront(:,1) & md2.diagnostic.icefront(:,2) & md2.diagnostic.icefront(:,end)),:);
     486                         end
     487
     488                         %Results fields
     489                         if isstruct(md1.results),
     490                                 md2.results=struct();
     491                                 solutionfields=fields(md1.results);
     492                                 for i=1:length(solutionfields),
     493                                         %get subfields
     494                                         solutionsubfields=fields(md1.results.(solutionfields{i}));
     495                                         for j=1:length(solutionsubfields),
     496                                                 field=md1.results.(solutionfields{i}).(solutionsubfields{j});
     497                                                 if length(field)==numberofvertices1,
     498                                                         md2.results.(solutionfields{i}).(solutionsubfields{j})=field(pos_node);
     499                                                 elseif length(field)==numberofelements1,
     500                                                         md2.results.(solutionfields{i}).(solutionsubfields{j})=field(pos_elem);
     501                                                 else
     502                                                         md2.results.(solutionfields{i}).(solutionsubfields{j})=field;
     503                                                 end
     504                                         end
     505                                 end
     506                         end
     507
     508                         %Keep track of pos_node and pos_elem
     509                         md2.mesh.extractedvertices=pos_node;
     510                         md2.mesh.extractedelements=pos_elem;
     511                 end % }}}
     512                 function md = extrude(md,varargin) % {{{
     513                         %EXTRUDE - vertically extrude a 2d mesh
     514                         %
     515                         %   vertically extrude a 2d mesh and create corresponding 3d mesh.
     516                         %   The vertical distribution can:
     517                         %    - follow a polynomial law
     518                         %    - follow two polynomial laws, one for the lower part and one for the upper part of the mesh
     519                         %    - be discribed by a list of coefficients (between 0 and 1)
     520                         %   
     521                         %
     522                         %   Usage:
     523                         %      md=extrude(md,numlayers,extrusionexponent);
     524                         %      md=extrude(md,numlayers,lowerexponent,upperexponent);
     525                         %      md=extrude(md,listofcoefficients);
     526                         %
     527                         %   Example:
     528                         %      md=extrude(md,8,3);
     529                         %      md=extrude(md,8,3,2);
     530                         %      md=extrude(md,[0 0.2 0.5 0.7 0.9 0.95 1]);
     531                         %
     532                         %   See also: MODELEXTRACT, COLLAPSE
     533
     534                         %some checks on list of arguments
     535                         if ((nargin>4) | (nargin<2) | (nargout~=1)),
     536                                 help extrude;
     537                                 error('extrude error message');
     538                         end
     539
     540                         %Extrude the mesh
     541                         if nargin==2, %list of coefficients
     542                                 list=varargin{1};
     543                                 if any(list<0) | any(list>1),
     544                                         error('extrusioncoefficients must be between 0 and 1');
     545                                 end
     546                                 extrusionlist=sort(unique([list(:);0;1]));
     547                                 numlayers=length(extrusionlist);
     548                         elseif nargin==3, %one polynomial law
     549                                 if varargin{2}<=0,
     550                                         help extrude;
     551                                         error('extrusionexponent must be >=0');
     552                                 end
     553                                 numlayers=varargin{1};
     554                                 extrusionlist=((0:1:numlayers-1)/(numlayers-1)).^varargin{2};
     555                         elseif nargin==4, %two polynomial laws
     556                                 numlayers=varargin{1};
     557                                 lowerexp=varargin{2};
     558                                 upperexp=varargin{3};
     559
     560                                 if varargin{2}<=0 | varargin{3}<=0,
     561                                         help extrude;
     562                                         error('lower and upper extrusionexponents must be >=0');
     563                                 end
     564
     565                                 lowerextrusionlist=[(0:2/(numlayers-1):1).^lowerexp]/2;
     566                                 upperextrusionlist=[(0:2/(numlayers-1):1).^upperexp]/2;
     567                                 extrusionlist=sort(unique([lowerextrusionlist 1-upperextrusionlist]));
     568
     569                         end
     570
     571                         if numlayers<2,
     572                                 error('number of layers should be at least 2');
     573                         end
     574                         if md.mesh.dimension==3,
     575                                 error('Cannot extrude a 3d mesh (extrude cannot be called more than once)');
     576                         end
     577
     578                         %Initialize with the 2d mesh
     579                         x3d=[];
     580                         y3d=[];
     581                         z3d=[];  %the lower node is on the bed
     582                         thickness3d=md.geometry.thickness; %thickness and bed for these nodes
     583                         bed3d=md.geometry.bed;
     584
     585                         %Create the new layers
     586                         for i=1:numlayers,
     587                                 x3d=[x3d; md.mesh.x];
     588                                 y3d=[y3d; md.mesh.y];
     589                                 %nodes are distributed between bed and surface accordingly to the given exponent
     590                                 z3d=[z3d; bed3d+thickness3d*extrusionlist(i)];
     591                         end
     592                         number_nodes3d=size(x3d,1); %number of 3d nodes for the non extruded part of the mesh
     593
     594                         %Extrude elements
     595                         elements3d=[];
     596                         for i=1:numlayers-1,
     597                                 elements3d=[elements3d;[md.mesh.elements+(i-1)*md.mesh.numberofvertices md.mesh.elements+i*md.mesh.numberofvertices]]; %Create the elements of the 3d mesh for the non extruded part
     598                         end
     599                         number_el3d=size(elements3d,1); %number of 3d nodes for the non extruded part of the mesh
     600
     601                         %Keep a trace of lower and upper nodes
     602                         mesh.lowervertex=NaN*ones(number_nodes3d,1);
     603                         mesh.uppervertex=NaN*ones(number_nodes3d,1);
     604                         mesh.lowervertex(md.mesh.numberofvertices+1:end)=1:(numlayers-1)*md.mesh.numberofvertices;
     605                         mesh.uppervertex(1:(numlayers-1)*md.mesh.numberofvertices)=md.mesh.numberofvertices+1:number_nodes3d;
     606                         md.mesh.lowervertex=mesh.lowervertex;
     607                         md.mesh.uppervertex=mesh.uppervertex;
     608
     609                         %same for lower and upper elements
     610                         mesh.lowerelements=NaN*ones(number_el3d,1);
     611                         mesh.upperelements=NaN*ones(number_el3d,1);
     612                         mesh.lowerelements(md.mesh.numberofelements+1:end)=1:(numlayers-2)*md.mesh.numberofelements;
     613                         mesh.upperelements(1:(numlayers-2)*md.mesh.numberofelements)=md.mesh.numberofelements+1:(numlayers-1)*md.mesh.numberofelements;
     614                         md.mesh.lowerelements=mesh.lowerelements;
     615                         md.mesh.upperelements=mesh.upperelements;
     616
     617                         %Save old mesh
     618                         md.mesh.x2d=md.mesh.x;
     619                         md.mesh.y2d=md.mesh.y;
     620                         md.mesh.elements2d=md.mesh.elements;
     621                         md.mesh.numberofelements2d=md.mesh.numberofelements;
     622                         md.mesh.numberofvertices2d=md.mesh.numberofvertices;
     623
     624                         %Update mesh type
     625                         md.mesh.dimension=3;
     626
     627                         %Build global 3d mesh
     628                         md.mesh.elements=elements3d;
     629                         md.mesh.x=x3d;
     630                         md.mesh.y=y3d;
     631                         md.mesh.z=z3d;
     632                         md.mesh.numberofelements=number_el3d;
     633                         md.mesh.numberofvertices=number_nodes3d;
     634                         md.mesh.numberoflayers=numlayers;
     635
     636                         %Ok, now deal with the other fields from the 2d mesh:
     637
     638                         %lat long
     639                         md.mesh.lat=project3d(md,'vector',md.mesh.lat,'type','node');
     640                         md.mesh.long=project3d(md,'vector',md.mesh.long,'type','node');
     641
     642                         %drag coefficient is limited to nodes that are on the bedrock.
     643                         md.friction.coefficient=project3d(md,'vector',md.friction.coefficient,'type','node','layer',1);
     644
     645                         %p and q (same deal, except for element that are on the bedrock: )
     646                         md.friction.p=project3d(md,'vector',md.friction.p,'type','element');
     647                         md.friction.q=project3d(md,'vector',md.friction.q,'type','element');
     648
     649                         %observations
     650                         md.inversion.vx_obs=project3d(md,'vector',md.inversion.vx_obs,'type','node');
     651                         md.inversion.vy_obs=project3d(md,'vector',md.inversion.vy_obs,'type','node');
     652                         md.inversion.vel_obs=project3d(md,'vector',md.inversion.vel_obs,'type','node');
     653                         md.surfaceforcings.mass_balance=project3d(md,'vector',md.surfaceforcings.mass_balance,'type','node');
     654                         md.surfaceforcings.precipitation=project3d(md,'vector',md.surfaceforcings.precipitation,'type','node');
     655                         md.balancethickness.thickening_rate=project3d(md,'vector',md.balancethickness.thickening_rate,'type','node');
     656                         md.surfaceforcings.monthlytemperatures=project3d(md,'vector',md.surfaceforcings.monthlytemperatures,'type','node');
     657
     658                         %results
     659                         if ~isnan(md.initialization.vx),md.initialization.vx=project3d(md,'vector',md.initialization.vx,'type','node');end;
     660                         if ~isnan(md.initialization.vy),md.initialization.vy=project3d(md,'vector',md.initialization.vy,'type','node');end;
     661                         if ~isnan(md.initialization.vz),md.initialization.vz=project3d(md,'vector',md.initialization.vz,'type','node');end;
     662                         if ~isnan(md.initialization.vel),md.initialization.vel=project3d(md,'vector',md.initialization.vel,'type','node');end;
     663                         if ~isnan(md.initialization.temperature),md.initialization.temperature=project3d(md,'vector',md.initialization.temperature,'type','node');end;
     664                         if ~isnan(md.initialization.waterfraction),md.initialization.waterfraction=project3d(md,'vector',md.initialization.waterfraction,'type','node');end;
     665
     666                         %bedinfo and surface info
     667                         md.mesh.elementonbed=project3d(md,'vector',ones(md.mesh.numberofelements2d,1),'type','element','layer',1);
     668                         md.mesh.elementonsurface=project3d(md,'vector',ones(md.mesh.numberofelements2d,1),'type','element','layer',md.mesh.numberoflayers-1);
     669                         md.mesh.vertexonbed=project3d(md,'vector',ones(md.mesh.numberofvertices2d,1),'type','node','layer',1);
     670                         md.mesh.vertexonsurface=project3d(md,'vector',ones(md.mesh.numberofvertices2d,1),'type','node','layer',md.mesh.numberoflayers);
     671
     672                         %elementstype
     673                         if ~isnan(md.flowequation.element_equation)
     674                                 oldelements_type=md.flowequation.element_equation;
     675                                 md.flowequation.element_equation=zeros(number_el3d,1);
     676                                 md.flowequation.element_equation=project3d(md,'vector',oldelements_type,'type','element');
     677                         end
     678
     679                         %verticestype
     680                         if ~isnan(md.flowequation.vertex_equation)
     681                                 oldvertices_type=md.flowequation.vertex_equation;
     682                                 md.flowequation.vertex_equation=zeros(number_nodes3d,1);
     683                                 md.flowequation.vertex_equation=project3d(md,'vector',oldvertices_type,'type','node');
     684                         end
     685                         md.flowequation.bordermacayeal=project3d(md,'vector',md.flowequation.bordermacayeal,'type','node');
     686                         md.flowequation.borderpattyn=project3d(md,'vector',md.flowequation.borderpattyn,'type','node');
     687                         md.flowequation.borderstokes=project3d(md,'vector',md.flowequation.borderstokes,'type','node');
     688
     689                         %boundary conditions
     690                         md.diagnostic.spcvx=project3d(md,'vector',md.diagnostic.spcvx,'type','node');
     691                         md.diagnostic.spcvy=project3d(md,'vector',md.diagnostic.spcvy,'type','node');
     692                         md.diagnostic.spcvz=project3d(md,'vector',md.diagnostic.spcvz,'type','node');
     693                         md.thermal.spctemperature=project3d(md,'vector',md.thermal.spctemperature,'type','node','layer',md.mesh.numberoflayers,'padding',NaN);
     694                         md.prognostic.spcthickness=project3d(md,'vector',md.prognostic.spcthickness,'type','node');
     695                         md.balancethickness.spcthickness=project3d(md,'vector',md.balancethickness.spcthickness,'type','node');
     696                         md.diagnostic.referential=project3d(md,'vector',md.diagnostic.referential,'type','node');
     697
     698                         %in 3d, pressureload: [node1 node2 node3 node4 element]
     699                         pressureload_layer1=[md.diagnostic.icefront(:,1:2)  md.diagnostic.icefront(:,2)+md.mesh.numberofvertices2d  md.diagnostic.icefront(:,1)+md.mesh.numberofvertices2d  md.diagnostic.icefront(:,3:4)]; %Add two columns on the first layer
     700                         pressureload=[];
     701                         for i=1:numlayers-1,
     702                                 pressureload=[pressureload ;pressureload_layer1(:,1:4)+(i-1)*md.mesh.numberofvertices2d pressureload_layer1(:,5)+(i-1)*md.mesh.numberofelements2d pressureload_layer1(:,6)];
     703                         end
     704                         md.diagnostic.icefront=pressureload;
     705
     706                         %connectivity
     707                         md.mesh.elementconnectivity=repmat(md.mesh.elementconnectivity,numlayers-1,1);
     708                         md.mesh.elementconnectivity(find(md.mesh.elementconnectivity==0))=NaN;
     709                         for i=2:numlayers-1,
     710                                 md.mesh.elementconnectivity((i-1)*md.mesh.numberofelements2d+1:(i)*md.mesh.numberofelements2d,:)...
     711                                         =md.mesh.elementconnectivity((i-1)*md.mesh.numberofelements2d+1:(i)*md.mesh.numberofelements2d,:)+md.mesh.numberofelements2d;
     712                         end
     713                         md.mesh.elementconnectivity(find(isnan(md.mesh.elementconnectivity)))=0;
     714
     715                         %materials
     716                         md.materials.rheology_B=project3d(md,'vector',md.materials.rheology_B,'type','node');
     717                         md.materials.rheology_n=project3d(md,'vector',md.materials.rheology_n,'type','element');
     718
     719                         %parameters
     720                         md.geometry.surface=project3d(md,'vector',md.geometry.surface,'type','node');
     721                         md.geometry.thickness=project3d(md,'vector',md.geometry.thickness,'type','node');
     722                         md.geometry.hydrostatic_ratio=project3d(md,'vector',md.geometry.hydrostatic_ratio,'type','node');
     723                         md.geometry.bed=project3d(md,'vector',md.geometry.bed,'type','node');
     724                         md.geometry.bathymetry=project3d(md,'vector',md.geometry.bathymetry,'type','node');
     725                         md.mesh.vertexonboundary=project3d(md,'vector',md.mesh.vertexonboundary,'type','node');
     726                         md.mask.elementonfloatingice=project3d(md,'vector',md.mask.elementonfloatingice,'type','element');
     727                         md.mask.vertexonfloatingice=project3d(md,'vector',md.mask.vertexonfloatingice,'type','node');
     728                         md.mask.elementongroundedice=project3d(md,'vector',md.mask.elementongroundedice,'type','element');
     729                         md.mask.vertexongroundedice=project3d(md,'vector',md.mask.vertexongroundedice,'type','node');
     730                         md.mask.elementonwater=project3d(md,'vector',md.mask.elementonwater,'type','element');
     731                         md.mask.vertexonwater=project3d(md,'vector',md.mask.vertexonwater,'type','node');
     732                         if ~isnan(md.inversion.cost_functions_coefficients),md.inversion.cost_functions_coefficients=project3d(md,'vector',md.inversion.cost_functions_coefficients,'type','node');end;
     733                         if ~isnan(md.inversion.min_parameters),md.inversion.min_parameters=project3d(md,'vector',md.inversion.min_parameters,'type','node');end;
     734                         if ~isnan(md.inversion.max_parameters),md.inversion.max_parameters=project3d(md,'vector',md.inversion.max_parameters,'type','node');end;
     735                         if ~isnan(md.qmu.partition),md.qmu.partition=project3d(md,'vector',md.qmu.partition','type','node');end
     736                         if(md.surfaceforcings.isdelta18o),md.surfaceforcings.temperatures_lgm=project3d(md,'vector',md.surfaceforcings.temperatures_lgm,'type','node');end
     737                         if(md.surfaceforcings.isdelta18o),md.surfaceforcings.temperatures_presentday=project3d(md,'vector',md.surfaceforcings.temperatures_presentday,'type','node');end
     738                         if(md.surfaceforcings.isdelta18o),md.surfaceforcings.precipitations_presentday=project3d(md,'vector',md.surfaceforcings.precipitations_presentday,'type','node');end
     739
     740                         %Put lithostatic pressure if there is an existing pressure
     741                         if ~isnan(md.initialization.pressure),
     742                                 md.initialization.pressure=md.constants.g*md.materials.rho_ice*(md.geometry.surface-md.mesh.z);
     743                         end
     744
     745                         %special for thermal modeling:
     746                         md.basalforcings.melting_rate=project3d(md,'vector',md.basalforcings.melting_rate,'type','node','layer',1);
     747                         if ~isnan(md.basalforcings.geothermalflux)
     748                                 md.basalforcings.geothermalflux=project3d(md,'vector',md.basalforcings.geothermalflux,'type','node','layer',1); %bedrock only gets geothermal flux
     749                         end
     750
     751                         %increase connectivity if less than 25:
     752                         if md.mesh.average_vertex_connectivity<=25,
     753                                 md.mesh.average_vertex_connectivity=100;
     754                         end
     755                        end % }}}
    93756                 function md = structtomodel(md,structmd) % {{{
    94757
     
    3851048                         md.settings         = settings();
    3861049                         md.solver           = solver();
    387                          if ismumps,
    388                                  md.solver           = addoptions(md.solver,DiagnosticVertAnalysisEnum,mumpsoptions);
     1050                         if ismumps(),
     1051                                 md.solver           = addoptions(md.solver,DiagnosticVertAnalysisEnum(),mumpsoptions());
    3891052                         else
    390                                  md.solver           = addoptions(md.solver,DiagnosticVertAnalysisEnum,iluasmoptions);
     1053                                 md.solver           = addoptions(md.solver,DiagnosticVertAnalysisEnum(),iluasmoptions());
    3911054                         end
    3921055                         md.cluster          = generic();
Note: See TracChangeset for help on using the changeset viewer.