Flow123d
boundaries.cc
Go to the documentation of this file.
1 /*!
2  *
3  * Copyright (C) 2007 Technical University of Liberec. All rights reserved.
4  *
5  * Please make a following refer to Flow123d on your project site if you use the program for any purpose,
6  * especially for academic research:
7  * Flow123d, Research Centre: Advanced Remedial Technologies, Technical University of Liberec, Czech Republic
8  *
9  * This program is free software; you can redistribute it and/or modify it under the terms
10  * of the GNU General Public License version 3 as published by the Free Software Foundation.
11  *
12  * This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
13  * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
14  * See the GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License along with this program; if not,
17  * write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 021110-1307, USA.
18  *
19  *
20  * $Id$
21  * $Revision$
22  * $LastChangedBy$
23  * $LastChangedDate$
24  *
25  * @file
26  * @brief Boundary conditions
27  * @ingroup mesh
28  *
29  */
30 
31 #include "system/system.hh"
32 #include "system/xio.h"
33 #include "mesh/mesh.h"
34 #include "mesh/boundaries.h"
35 #include "mesh/accessors.hh"
36 
37 
39 
40 
42 : edge_idx_(Mesh::undef_idx), bc_ele_idx_(Mesh::undef_idx),
43  mesh_(NULL)
44 {}
45 
46 
48  return &( mesh_->bc_elements[bc_ele_idx_] );
49 }
50 
52  return &( mesh_->edges[edge_idx_] );
53 }
54 
56 {
57  return mesh_->element_accessor(bc_ele_idx_, true);
58 }
59 
60 
61 
62 //=============================================================================
63 // READ DATA OF BOUNDARY CONDITIONS
64 //=============================================================================
65 /*
66 void read_boundary( struct Mesh *mesh , const string &boundary_filename)
67 {
68  FILE *in; // input file
69  char line[ LINE_SIZE ]; // line of data file
70 // int where;
71  int bcd_id, n_tags;
72  double scalar, flux, sigma;
73  BoundaryIter bcd;
74  ElementFullIter ele = ELEMENT_FULL_ITER_NULL(mesh);
75 
76  ASSERT(!( mesh == NULL ),"NULL as argument of function read_boundary_list()\n");
77  xprintf( Msg, "Reading boundary conditions...");
78 
79  in = xfopen( boundary_filename, "rt" );
80  skip_to( in, "$BoundaryConditions" );
81  xfgets( line, LINE_SIZE - 2, in );
82 
83  int n_boundaries = atoi( xstrtok( line) );
84  //OldBcdInput::instance()->bcd_ids_.resize(n_boundaries);
85  Boundary::id_to_bcd.reserve(n_boundaries);
86 
87  int group_number=0;
88 
89  for(int i_bcd=0; i_bcd < n_boundaries; i_bcd++) {
90  // Read one line
91  xfgets( line, LINE_SIZE - 2, in );
92  // Parse the line
93  bcd_id = atoi( xstrtok( line) );
94  //OldBcdInput::instance()->bcd_ids_[i_bcd] = bcd_id;
95  // DBGMSG("boundary id: %d \n",bcd_id);
96 
97  unsigned int type = atoi( xstrtok( NULL) );
98 
99  // physical data - should be moved to water_linsys
100  switch( type ) {
101  case DIRICHLET:
102  scalar = atof( xstrtok( NULL) );
103  flux = 0.0;
104  sigma = 0.0;
105  break;
106  case NEUMANN:
107  flux = atof( xstrtok( NULL) );
108  sigma = 0.0;
109  scalar = 0.0;
110  break;
111  case NEWTON:
112  scalar = atof( xstrtok( NULL) );
113  sigma = atof( xstrtok( NULL) );
114  flux = 0.0;
115  break;
116  default :
117  xprintf(UsrErr,"Unknown type of boundary condition - cond # %d, type %c\n", bcd_id, bcd->type );
118  break;
119  }
120 
121  unsigned int bcd_idx;
122  unsigned int where = atoi( xstrtok( NULL) );
123  int eid, sid, n_exterior;
124  SideIter sde;
125 
126  switch( where ) {
127  case 2: // SIDE_EL - BC given by element and its local side number
128  eid = atoi( xstrtok( NULL) );
129  sid = atoi( xstrtok( NULL) );
130 
131  // find and set the side
132  ele = mesh->element.find_id( eid );
133  if( sid < 0 || sid >= ele->n_sides() )
134  xprintf(UsrErr,"Boundary %d has incorrect reference to side %d\n", bcd_id, sid );
135  bcd = ele->side(sid) -> cond();
136  bcd_idx = ele->side(sid) -> cond_idx();
137 
138  ASSERT( bcd != NULL, "Missing boundary object.");
139  bcd->type = type;
140  bcd->flux = flux;
141  bcd->scalar = scalar;
142  bcd->sigma = sigma;
143 
144  break;
145  case 3: // SIDE_E - BC given only by element, apply to all its sides
146 
147  xprintf(UsrErr, "Element only BCD are not supported.\n");
148  eid = atoi( xstrtok( NULL) );
149 
150  // find and set all exterior sides, possibly add more boundaries
151  ele = mesh->element.find_id( eid );
152  n_exterior=0;
153  FOR_ELEMENT_SIDES(ele, li) {
154  sde = ele->side( li );
155  bcd=sde->cond();
156  if (bcd) {
157 
158  if (n_exterior > 0) {
159  xprintf(UsrErr, "Implicitly setting BC %d on more then one exterior sides of the element %d.\n", bcd_id, eid);
160  //BoundaryFullIter new_bcd = mesh->boundary.add_item();
161  // *new_bcd = *bcd;
162  //bcd=new_bcd;
163  }
164  bcd->type = type;
165  bcd->flux = flux;
166  bcd->scalar = scalar;
167  bcd->sigma = sigma;
168  n_exterior++;
169  }
170  }
171 
172  break;
173  default:
174  xprintf(UsrErr,"Unknown entity for boundary condition - cond # %d, ent. %c\n", bcd_id, where );
175  break;
176  }
177  // DBGMSG("fbcd: %d %d %d %d \n", i_bcd, bcd - mesh->boundary.begin(), bcd->side->element().index(), bcd->side->el_idx() );
178  *(Boundary::id_to_bcd.add_item(bcd_id)) = bcd_idx;
179 
180 
181  //TODO: if group is necessary set it for all bcd in case where == SIDE_E
182  n_tags = atoi( xstrtok( NULL) );
183  if( n_tags > 0 ) {
184  int group_id = atoi( xstrtok( NULL) );
185  flow::VectorId<int>::FullIter group_iter( mesh->bcd_group_id.find_id(group_id) );
186 
187  if ( group_iter == mesh->bcd_group_id.end() ) {
188  // not found -> create new group
189  group_iter = mesh->bcd_group_id.add_item(group_id);
190  }
191  bcd->group = group_iter.index(); // in fact we do not use integres stored in the vector, but we use index
192  }
193 
194 
195  }
196 
197  xfclose( in );
198  xprintf( MsgVerb, " %d conditions readed. ", mesh->n_boundaries() );
199  xprintf( Msg, "O.K.\n");
200 
201 }
202  */
203 
204 
205 
206 
207 
208 //=============================================================================
209 // FILL EDGE PART OF MH MATRIX WHICH BELONGS TO BOUNDARIES
210 //=============================================================================
211 // TODO: be more sure that BC are applied well
212 /*
213 void boundary_calculation_mh( struct Mesh *mesh )
214 {
215  struct Boundary *bcd;
216  struct Edge *edg;
217 
218  xprintf( Msg, "Calculating properties of boundaries... ");
219  ASSERT( NONULL(mesh) ,"NULL as argument of function boundary_calculation_mh()\n");
220  FOR_BOUNDARIES(mesh, bcd ) {
221  edg=bcd->side->edge();
222  // following code may not work if a BC is applied to an edge with neighbouring
223  // in such a case we need to add to the f_val, nevertheless the original code
224  // does not do it as well
225  //ASSERT(edg->n_sides == 1,"Boundary condition %d on an internal edge %d!\n",bcd->id,edg->id);
226  //ASSERT(edg->neigh_vb == NULL,"Boundary condition %d on an neighbouring edge %d!",bcd->id,edg->id);
227  switch( bcd->type ) {
228  // for the dirichlet condition it should be checked, that the corresponding
229  // row in the MH matrix is zero except the diagonal
230  case DIRICHLET:
231  edg->f_val = -1.0;
232  edg->f_rhs = -1.0 * bcd->scalar;
233  break;
234  case NEUMANN:
235  edg->f_val = 0.0;
236  edg->f_rhs = bcd->flux * bcd->side->metric();
237  break;
238  case NEWTON:
239  edg->f_val = -1.0 * bcd->side->metric()*bcd->sigma;
240  edg->f_rhs = edg->f_val * bcd->scalar;
241  break;
242  default:
243  xprintf(PrgErr,"Unknown type of boundary condition\n");
244  }
245  }
246  xprintf( Msg, "O.K.\n");
247 }*/
248 //-----------------------------------------------------------------------------
249 // vim: set cindent:
250