00001 #include "partint.h"
00002
00003
00004 bool In_tet(dir_sons Tet[4], D3vector corn[8], D3vector V, double h) {
00005
00006 const double EPS = -1.0e-5*h*h*h*h;
00007
00008 if(Calc_bary_weights(corn[Tet[0]],corn[Tet[1]],corn[Tet[2]],corn[Tet[3]],V,0)<=EPS)
00009 return false;
00010 if(Calc_bary_weights(corn[Tet[0]],corn[Tet[1]],corn[Tet[2]],corn[Tet[3]],V,1)<=EPS)
00011 return false;
00012 if(Calc_bary_weights(corn[Tet[0]],corn[Tet[1]],corn[Tet[2]],corn[Tet[3]],V,2)<=EPS)
00013 return false;
00014 if(Calc_bary_weights(corn[Tet[0]],corn[Tet[1]],corn[Tet[2]],corn[Tet[3]],V,3)<=EPS)
00015 return false;
00016 return true;
00017 }
00018
00019 bool In_tetbo(Tetraeder_storage* tet, D3vector corn[28], D3vector V) {
00020 if(Calc_bary_weights(corn[tet->N0()],corn[tet->N1()],
00021 corn[tet->N2()],corn[tet->N3()],
00022 V,0)<0.0)
00023 return false;
00024 if(Calc_bary_weights(corn[tet->N0()],corn[tet->N1()],
00025 corn[tet->N2()],corn[tet->N3()],
00026 V,1)<0.0)
00027 return false;
00028 if(Calc_bary_weights(corn[tet->N0()],corn[tet->N1()],
00029 corn[tet->N2()],corn[tet->N3()],
00030 V,2)<0.0)
00031 return false;
00032 if(Calc_bary_weights(corn[tet->N0()],corn[tet->N1()],
00033 corn[tet->N2()],corn[tet->N3()],
00034 V,3)<0.0)
00035 return false;
00036 return true;
00037 }
00038
00039 void Set_tets(dir_sons Tets[6][4]) {
00040
00041 Tets[0][0] = WNTd;
00042 Tets[0][1] = WNDd;
00043 Tets[0][2] = WSTd;
00044 Tets[0][3] = ESTd;
00045
00046
00047 Tets[1][0] = ESTd;
00048 Tets[1][1] = WNDd;
00049 Tets[1][2] = WSTd;
00050 Tets[1][3] = ESDd;
00051
00052
00053 Tets[2][0] = WNDd;
00054 Tets[2][1] = WSDd;
00055 Tets[2][2] = WSTd;
00056 Tets[2][3] = ESDd;
00057
00058
00059 Tets[3][0] = ESTd;
00060 Tets[3][1] = WNDd;
00061 Tets[3][2] = ESDd;
00062 Tets[3][3] = ENDd;
00063
00064
00065 Tets[4][0] = ENTd;
00066 Tets[4][1] = WNTd;
00067 Tets[4][2] = ESTd;
00068 Tets[4][3] = ENDd;
00069
00070
00071 Tets[5][0] = WNTd;
00072 Tets[5][1] = WNDd;
00073 Tets[5][2] = ESTd;
00074 Tets[5][3] = ENDd;
00075 }
00076
00077
00078
00079 void partHelm_FE(Variable *f, double x, double y, double z, double q) {
00080 Grid* grid;
00081 grid = f->Give_grid();
00082 Index3D I,J;
00083 D3vector V;
00084 const int max_lev = grid->Max_level();
00085 double h;
00086 dir_sons Tets[6][4];
00087 int num;
00088
00089 h = grid->Give_finest_mesh_size();
00090 V = grid->back_transform_coord(D3vector(x,y,z));
00091 I = back_coordinate(V,max_lev);
00092 Set_tets(Tets);
00093
00094 D3vector corn[28];
00095 bool found;
00096 Tetraeder_storage* found_tet;
00097
00098 for(unsigned int i=0;i<8;++i) {
00099 corn[i] = D3vector(x1DCoord((dir_sons)i),
00100 y1DCoord((dir_sons)i),
00101 z1DCoord((dir_sons)i));
00102 }
00103
00104 if(grid->Give_cell_typ(I)==int_cell) {
00105
00106
00107
00108
00109
00110
00111
00112
00113 V = (D3vector(x,y,z) - grid->transform_coord(I.neighbour(WSDd))) / h;
00114
00115 found=false;
00116 int ii=0;
00117 for(;ii<6&&(found==false);++ii) {
00118 found = In_tet(Tets[ii],corn,V,h);
00119 }
00120 if(found==false) cout << " error in partHelm_FE found tet! " << endl;
00121 --ii;
00122
00123 for(unsigned int i=0;i<4;++i) {
00124 J=I.neighbour(Tets[ii][i]);
00125
00126 grid->Give_variable(J,max_lev)[f->Number_variable()] +=
00127 q * Calc_bary_weights(corn[Tets[ii][0]],corn[Tets[ii][1]],
00128 corn[Tets[ii][2]],corn[Tets[ii][3]],V,i);
00129 }
00130 } else if(grid->Give_cell_typ(I)==fine_bo_cell) {
00131
00132
00133
00134
00135
00136
00137
00138
00139
00140
00141
00142
00143
00144
00145
00146 BoCell* boc = grid->Give_Bo_cell(I);
00147 for(num=0;num<boc->Give_total_number_points();++num) {
00148 corn[num] = boc->coord(num , boc->hhh) / h;
00149 }
00150
00151 found_tet=NULL;
00152 Tetraeder_storage* tet;
00153 for(tet=boc->Give_tets();tet!=NULL && found_tet==NULL;tet=tet->Next()) {
00154 if(In_tetbo(tet,corn,V)) {
00155 found_tet = tet;
00156 }
00157 }
00158 if(found_tet==NULL) {
00159 int count = 0;
00160 for(unsigned int i=0;i<8;++i) {
00161 J=I.neighbour((dir_sons)i);
00162 if (grid->Give_type(J) == nearb)
00163 count++;
00164 }
00165 for(unsigned int i=0;i<8;++i) {
00166 J=I.neighbour((dir_sons)i);
00167 if (grid->Give_type(J) == nearb) {
00168 grid->Give_variable(J,max_lev)[f->Number_variable()] += 1.0/(double)count * q;
00169 }
00170 }
00171 }
00172 else {
00173 for(unsigned int i=0;i<4;++i) {
00174 if(i==0) num = found_tet->N0();
00175 if(i==1) num = found_tet->N1();
00176 if(i==2) num = found_tet->N2();
00177 if(i==3) num = found_tet->N3();
00178 boc->vars[num][f->Number_variable()] +=
00179 q * Calc_bary_weights(corn[found_tet->N0()],corn[found_tet->N1()],
00180 corn[found_tet->N2()],corn[found_tet->N3()],
00181 V,i) / found_tet->Det();
00182
00183
00184
00185
00186
00187
00188
00189
00190
00191 }
00192 }
00193 }
00194 else {
00195
00196
00197
00198
00199
00200
00201
00202
00203
00204
00205
00206
00207
00208
00209
00210
00211 }
00212
00213
00214
00215
00216
00217
00218
00219 }
00220
00221 inline double weight(double x, dir1D d, double h) {
00222 if(Rd==d) return x;
00223 return h-x;
00224 }
00225
00226 void partInterp(Variable *f, double x, double y, double z, double *q) {
00227 Grid* grid;
00228 grid = f->Give_grid();
00229 Index3D I,J;
00230 D3vector V;
00231 const int max_lev = grid->Max_level();
00232 double h, hhh;
00233
00234 h = grid->Give_finest_mesh_size();
00235 hhh = h*h*h;
00236
00237
00238 V = grid->back_transform_coord(D3vector(x,y,z));
00239 I = back_coordinate(V,max_lev);
00240
00241 *q=0.0;
00242
00243 if(grid->Give_cell_typ(I)==int_cell) {
00244
00245
00246
00247
00248
00249
00250
00251 V = D3vector(x,y,z) - grid->transform_coord(I.neighbour(WSDd));
00252 for(unsigned int i=0;i<8;++i) {
00253 J=I.neighbour((dir_sons)i);
00254 *q += grid->Give_variable(J,max_lev)[f->Number_variable()] *
00255 weight(V.x,x1DCoord((dir_sons)i),h) *
00256 weight(V.y,y1DCoord((dir_sons)i),h) *
00257 weight(V.z,z1DCoord((dir_sons)i),h) / hhh;
00258 }
00259 }
00260 else if(grid->Give_cell_typ(I)==fine_bo_cell) {
00261 int count = 0;
00262 for(unsigned int i=0;i<8;++i) {
00263 J=I.neighbour((dir_sons)i);
00264 if (grid->Give_type(J) == nearb)
00265 count++;
00266 }
00267 for(unsigned int i=0;i<8;++i) {
00268 J=I.neighbour((dir_sons)i);
00269 if (grid->Give_type(J) == nearb) {
00270 *q += grid->Give_variable(J,max_lev)[f->Number_variable()] / (double)count;
00271 }
00272 }
00273 }
00274 else {
00275
00276 }
00277
00278 }