ParMooN
 All Classes Functions Variables Friends Pages
5SpotProblem.h
1 // Bechmark for Darcy problem, exact solution is known
2 // see Arif Masud, Thomas J.R. Hughes: "A stabilized mixed finite element
3 // method for Darcy flow", chapter 4.2
4 //
5 // Problem: The source term consists of two point sources at (0,0) and (1,1).
6 // These are Dirac delta functions. To model these we use equivalent
7 // prescribed flows at the first edges touching the corner points (0,0) and
8 // (1,1). However for this to work we need to know the edge length and the
9 // order of the used finite elements. That's why one has to modify the
10 // function "FluxBoundValue" every time the grid is refined..
11 //
12 // Problem 2: On all other parts of the boundary we prescribe u.n=0 for
13 // symmetry reasons. However the solution given in ExactP, ExactU1 and
14 // ExactU2 does not fulfill this. To achieve this, we would have to continue
15 // the source/sink pattern until infinity.
16 
17 void ExampleFile()
18 {
19  OutPut("Example: 5SpotProblem.h\n");
20  OutPut(" This works so far only on one level with a regular grid\n");
21 }
22 
23 // ========================================================================
24 // exact solution
25 // ========================================================================
26 inline double r(double x,double y,double x0,double y0)
27 { return (x-x0)*(x-x0) + (y-y0)*(y-y0); }
28 void ExactU1(double x, double y, double *values)
29 {
30  double r0,r1,r2,r3,r4;
31  r0 = r(x,y, 0, 0);
32  r1 = r(x,y, 1, 1);
33  r2 = r(x,y,-1, 1);
34  r3 = r(x,y,-1,-1);
35  r4 = r(x,y, 1,-1);
36  values[0] = (x/r0 - (x-1)/r1 - (x+1)/r2 - (x+1)/r3 - (x-1)/r4)/4;
37  values[1] = 0;
38  values[2] = -(x*y/(r0*r0) - (x-1)*(y-1)/(r1*r1) - (x+1)*(y-1)/(r2*r2)
39  - (x+1)*(y+1)/(r3*r3) - (x-1)*(y+1)/(r4*r4) )/2;
40  values[3] = 0;
41 }
42 void ExactU2(double x, double y, double *values)
43 {
44  double r0,r1,r2,r3,r4;
45  r0 = r(x,y, 0, 0);
46  r1 = r(x,y, 1, 1);
47  r2 = r(x,y,-1, 1);
48  r3 = r(x,y,-1,-1);
49  r4 = r(x,y, 1,-1);
50  values[0] = (y/r0 - (y-1)/r1 - (y-1)/r2 - (y+1)/r3 - (y+1)/r4)/4;;
51  values[1] = -(x*y/(r0*r0) - (x-1)*(y-1)/(r1*r1) - (x+1)*(y-1)/(r2*r2)
52  - (x+1)*(y+1)/(r3*r3) - (x-1)*(y+1)/(r4*r4) )/2;
53  values[2] = 0;
54  values[3] = 0;
55 }
56 void ExactP(double x, double y, double *values)
57 {
58 
59  int n_plus = 1;
60  int n_minus = 4;
61  double plus[] = {0,0,
62  2,0, 2,2, 0,2, -2,2, -2,0, -2,-2, 0,-2, 2,-2,
63  4,0, 4,2, 4,4, 2,4, 0,4, -2,4, -4,4, -4,2, -4,0, -4,-2, -4,-4, -2,-4, 0,-4, 2,-4, 4,-4, 4,-2};
64  double minus[] = {1,1, -1,1, -1,-1, 1,-1,
65  3,1, 3,3, 1,3, -1,3, -3,3, -3,1, -3,-1, -3,-3, -1,-3, 1,-3, 3,-3, 3,-1,
66  5,1, 5,3, 5,5, 3,5, 1,5, -1,5, -3,5, -5,5, -5,3, -5,1, -5,-1, -5,-3, -5,-5, -3,-5, -1,-5, 1,-5, 3,-5, 5,-5, 5,-3, 5,-1};
67  values[0] = 0;
68  for(int i=0; i<n_plus; i++)
69  values[0] -= log(sqrt(r(x,y,plus[2*i],plus[2*i+1])));
70  for(int i=0; i<n_minus; i++)
71  values[0] += log(sqrt(r(x,y,minus[2*i],minus[2*i+1])));
72  values[0] *= 0.25;
73 
74  values[1] = 0;
75  for(int i=0; i<n_plus; i++)
76  values[1] -= (x-plus[2*i])/r(x,y,plus[2*i],plus[2*i+1]);
77  for(int i=0; i<n_minus; i++)
78  values[1] += (x-minus[2*i])/r(x,y,minus[2*i],minus[2*i+1]);
79  values[1] *= 0.25;
80 
81  values[2] = 0;
82  for(int i=0; i<n_plus; i++)
83  values[2] -= (y-plus[2*i+1])/r(x,y,plus[2*i],plus[2*i+1]);
84  for(int i=0; i<n_minus; i++)
85  values[2] += (y-minus[2*i+1])/r(x,y,minus[2*i],minus[2*i+1]);
86  values[2] *= 0.25;
87  /*
88  double r0,r1,r2,r3,r4;
89  r0 = r(x,y, 0, 0);
90  r1 = r(x,y, 1, 1);
91  r2 = r(x,y,-1, 1);
92  r3 = r(x,y,-1,-1);
93  r4 = r(x,y, 1,-1);
94  values[0] = -(log(sqrt(r0))-log(sqrt(r1))-log(sqrt(r2))
95  -log(sqrt(r3))-log(sqrt(r4)) )/4;
96  values[1] = -(x/r0 - (x-1)/r1 - (x+1)/r2 - (x+1)/r3 - (x-1)/r4)/4;
97  values[2] = -(y/r0 - (y-1)/r1 - (y-1)/r2 - (y+1)/r3 - (y+1)/r4)/4;
98  */
99  values[3] = 0;
100 }
101 
102 
103 
104 // ========================================================================
105 // boundary conditions
106 // ========================================================================
107 void BoundCondition(int bdComp, double t, BoundCond &cond)
108 { cond = DIRICHLET; }
109 // u \cdot n
110 void FluxBoundValue(int bdComp, double Param, double &value)
111 {
112  value = 0;
113  double h = 1.0/32.0;
114  int order = 1;
115  switch(bdComp)
116  {
117  case 0:
118  if (Param<h)
119  {
120  value=-(1-Param/h)/(4*h);
121  if( order == 2)
122  value = -(3/(8*h))*(1-2*Param/h + Param*Param/(h*h));
123  }
124  break;
125  case 1:
126  if(Param>1-h)
127  {
128  value=(1-(1-Param)/h)/(4*h);
129  if( order == 2)
130  value = (3/(8*h))*(1-2*(1-Param)/h + (1-Param)*(1-Param)/(h*h));
131  }
132  break;
133  case 2:
134  if (Param<h)
135  {
136  value=(1-Param/h)/(4*h);
137  if( order == 2)
138  value = (3/(8*h))*(1-2*Param/h + Param*Param/(h*h));
139  }
140  break;
141  case 3:
142  if(Param>1-h)
143  {
144  value=-(1-(1-Param)/h)/(4*h);
145  if( order == 2)
146  value = -(3/(8*h))*(1-2*(1-Param)/h + (1-Param)*(1-Param)/(h*h));
147  }
148  break;
149  default: cout << "wrong boundary part number" << endl;
150  break;
151  }
152 }
153 // ========================================================================
154 // coefficients for Stokes form: A, B1, B2, f1, f2
155 // ========================================================================
156 void LinCoeffs(int n_points, double *X, double *Y,
157  double **parameters, double **coeffs)
158 {
159  int i;
160  double *coeff;
161 
162  for(i=0;i<n_points;i++)
163  {
164  coeff = coeffs[i];
165 
166  if ( (X[i] < 0.5 && Y[i]<0.5) || (X[i] > 0.5 && Y[i]>0.5) )
167  coeff[0] = 2.0;
168  else
169  coeff[0] = 200.0;
170  // RHS for exact solution
171  coeff[1] = 0; // f1
172  coeff[2] = 0; // f2
173  coeff[3] = 0; // g
174  }
175 }
176 
177