source: issm/trunk-jpl/externalpackages/petsc-dev/src/include/sieve/UFC.hh@ 11896

Last change on this file since 11896 was 11896, checked in by habbalf, 13 years ago

petsc-dev : Petsc development code in external packages. Mercurial updates

File size: 47.4 KB
Line 
1/*
2
3Routines for linking UFC to Sieve and PETSc
4
5*/
6
7#include "Mesh.hh"
8#include <petscmat.h>
9#include <ufc.h>
10
11//we SHOULD have some overlying "problem" object. Let's do that here!
12
13#if 0
14
15namespace ALE {
16 class sieve_mesh_wrapper : ufc::mesh {
17
18 public:
19 Obj<PETSC_MESH_TYPE> m;
20 sieve_mesh_wrapper(Obj<PETSC_MESH_TYPE> mesh) {
21 m = mesh;
22 Obj<PETSC_MESH_TYPE::real_section_type> coordinates = m->getRealSection("coordinates");
23 int dim = m->getDimension();
24 topological_dimension = dim;
25 geometric_dimension = m->getFiberDimension(*m->depthStratum(0)->begin());
26 num_entities = new unsigned int[dim+1];
27 int depth = m->depth();
28 for (int i = 0; i < depth; i++) {
29 num_entities[i] = 0;
30 }
31 if (depth == 1) {
32 num_entities[0] = m->depthStratum(0);
33 num_entities[dim] = m->heightStratum(0);
34 } else {
35 if (depth != dim+1) throw Exception("Cannot handle partially interpolated sieves.");
36 for (int i = 0; i < dim+1; i++) {
37 num_entities[i] = m->getDepthStratum(i)->size();
38 }
39
40 }
41 }
42
43 };
44
45 class sieve_cell_wrapper : ufc::cell {
46 public:
47 Obj<PETSC_MESH_TYPE> m; // the presently associated mesh
48 int num_corners; //for the sake of clarity; the number of vertices
49 PETSC_MESH_TYPE::point_type current_point; // the presently associated sieve cell
50
51
52 sieve_cell_wrapper() {
53 }
54 sieve_cell_wrapper(ufc::finite_element finite_element) {
55 //properly initialize the cell from the form
56 int geometric_dimension = m->getRealSection("coordinates")->getFiberDimension(m->depthStratum(0)->begin());
57 if (finite_element->cell_shape() == ufc::interval) {
58 num_corners = 2;
59 topological_dimension = m->getDimension(); //we must clarify what this means in the mesh library
60 element_entities = new int *[2];
61 element_entities[0] = new int[2]; //vertices
62 element_entities[1] = new int[1]; //line
63 double * tmpcoords = new double[coorddim*2];
64 coordinates = new double *[2];
65 for (int i = 0; i < 2; i++) {
66 coordinates[i] = &tmpcoords[coorddim*i];
67 }
68 } else if (finite_element->cell_shape() == ufc::triangle) {
69 num_corners = 3;
70 element_entities = new int *[3];
71 element_entities[0] = new int[3]; //vertices
72 element_entities[1] = new int[3]; //edges
73 element_entities[2] = new int[1]; //cell
74 double * tmpcoords = new double[coorddim*3];
75 coordinates = new double *[3];
76 for (int i = 0; i < 3; i++) {
77 coordinates[i] = &tmpcoords[coorddim*i];
78 }
79 } else if (finite_element->cell_shape() == ufc::tetrahedron) {
80 num_corners = 4;
81 element_entities = new int *[2];
82 element_entities[0] = new int[4]; //vertices
83 element_entities[1] = new int[6]; //edges
84 element_entities[2] = new int[4]; //faces
85 element_entities[3] = new int[1]; //tetrahedron
86 double * tmpcoords = new double[coorddim*4];
87 coordinates = new double *[4];
88 for (int i = 0; i < 4; i++) {
89 coordinates[i] = &tmpcoords[coorddim*i];
90 }
91 } else throw Exception("Unsupported geometry");
92 }
93 ~sieve_cell_wrapper() {
94 }
95 void setMesh(Obj<PETSC_MESH_TYPE> mesh) {
96 m = mesh;
97 }
98 Obj<PETSC_MESH_TYPE> getMesh() {
99 return m;
100 }
101 void setCell(PETSC_MESH_TYPE::point_type p) {
102 if (m->height(p) != 0) throw Exception("sieve_cell_wrapper: the point must be a cell");
103 current_point = p;
104 //copy over the coordinates through the restrictClosure and copy
105 const double * coords = m->;
106 for (int i = 0; i < num_corners; i++) {
107 for (int j = 0; j < dim; j++) {
108 coordinates[i][j] = coords[i*coordim+j];
109 }
110 }
111 //copy over the entity indices such that they're consistent with the
112 }
113 void reorientSieveCell(PETSC_MESH_TYPE::point_type p) {
114 //changing the orientation will be hard; keep it the same for now as it should orient normals right
115 //this will not be so bad in the long run
116
117 }
118 Obj<PETSC_MESH_TYPE::sieve_type::oConeArray> reorderSieveClosure(PETSC_MESH_TYPE::point_type p) {
119 //return m->getSieve()->closure(p); //null reorder for now. NEI! the oriented closure!
120 return PETSC_MESH_TYPE::sieve_alg_type::orientedClosure(m, m->getArrowSection("orientation"), p);
121 }
122 void reorderSieveRestrictClosure(const double * coefficients) {
123 //order the restricted closure given in coefficients based upon the cell mapping here
124 }
125
126 };
127
128 class sieve_function_wrapper : ufc::function {
129 public:
130 (*_func)(double * values, const double * coords); //the simple function that computes the value based on the coordinates.
131 int _rank; //the number of values returned by the function
132
133 sieve_function_wrapper(){};
134 sieve_function_wrapper(const double * (*func)(const double * coords), int rank) {
135 _func = func;
136 _rank = rank;
137 }
138 const double * (*)(const double *) getFunction() {
139 return _func;
140 }
141 void setFunction(const double * (*func)(const double * coords), int rank) {
142 _func = func;
143 }
144 void evaluate(double * values, const double * coordinates, ufc::cell &cell) {
145 _func(values, coordinates);
146 }
147 };
148
149 //this class takes coordinates in a cell and produces output based upon those coordinates and the section over the mesh in that cell
150 //might come in handy for generalized MG, etc.
151 class section_wrapper_function : ufc::function {
152 public:
153
154 ALE::Obj<PETSC_MESH_TYPE> _m;
155 ALE::Obj<PETSC_MESH_TYPE::section_type> _s;
156 //PETSC_MESH_TYPE::point_type c;
157
158 ufc::form * _form;
159 ufc::finite_element * _finite_element;
160 ufc::cell_integral * _cell_integral;
161
162 section_wrapper_function(){};
163 section_wrapper_function(Obj<PETSC_MESH_TYPE> m, Obj<PETSC_MESH_TYPE::section_type> s, ufc::form form, ufc::finite_element finite_element, ufc::cell_integral::cell_integral){
164 _m = m;
165 _s = s;
166 _form = form;
167 _finite_element = finite_element;
168 _cell_integral = cell_integral;
169 }
170
171 void evaluate(double * values, const double * coordinates, ufc::cell &cell)
172 {
173 //evaluate the degrees of freedom on the interior of the given cell; note that this requires that coordinates be within the cell to really make sense.
174 //note for the future: we could wrap this easily into the multigrid routines
175 //we need an additional aggregation array of size value_rank;
176 const double * coefficients = m->restrictClosure(_s, cell->current_point);
177 const double * tmp_values = new double[_finite_element->value_rank()];
178 for (int i = 0; i < _finite_element->value_rank(); i++) {
179 values[i] = 0.;
180 }
181 for (int i = 0; i < _finite_element->value_dimension(); i++) { //loop over basis functions
182 _finite_element->evaluate_basis(i, tmp_values, coordinates, cell);
183 for (int j = 0; j < _finite_element->value_rank()+1; i++) {
184 values[i] += coefficients[i*(finite_element->value_rank()+1)+j]*tmp_values[j];
185 }
186 }
187 delete tmp_values;
188 }
189 };
190
191 class boundary_condition {
192 public:
193 PetscBool (*_func)(PETSC_MESH_TYPE::point_type, const double *);
194 int marker;
195 int cellmarker;
196
197 boundary_condition(){};
198 boundary_condition (PetscBool (*func)(PETSC_MESH_TYPE::point_type, const double *), int mark = 1, int cellmark = 2) {
199
200 }
201 void applyBC(Obj<PETSC_MESH_TYPE> m) {
202 }
203 };
204
205 PetscBool Scalar_Dirichlet_Pred(PETSC_MESH_TYPE::point_type p, const double * coords) {
206 //set up the marker
207 //if anything in the star of the thing has support size 1 but not height 0 then the thing's on the boundary! mark it!
208 Obj<PETSC_MESH_TYPE::sieve_type::supportArray> star =
209 }
210
211 class UFCProblem : ALE::ParallelObject {
212 public:
213 //sieve parts
214 Obj<PETSC_MESH_TYPE> _mesh;
215
216 //UFC parts
217 //Forms:
218 ufc::form * _bform;
219 ufc::form * _lform;
220 //Coefficients:
221 int _num_bcoefficients;
222 double * b_w;
223 int _num_lcoefficients;
224 double * l_w;
225 //Finite Elements:
226 int _num_finite_elements;
227 ufc::finite_element ** _finite_elements;
228 //"Coefficient" elements from the RHS linear forms
229 int _num_coefficient_elements;
230 ufc::finite_element ** _coefficient_elements;
231 //Cell types; perhaps not
232 int _num_cell_types;
233 ufc::cell ** _cell;
234 //Cell integrals
235 int _num_cell_integrals;
236 ufc::cell_integral * _cell_integrals;
237 //Functions:
238 // - The RHS Function
239 ufc::function * _rhs_funct;
240 // - The "Exact Solution"
241 ufc::function * _exact_solution;
242 //We also need to define some sort of predicate system for the boundary like dolfin;
243 //This will involve some setting of the boundary marker, not necessarily based upon the topological boundary, but usually that.
244 //Initialization
245 UFCProblem(){};
246 //give it a mesh, give it a form, mark boundary segments through some f
247 UFCProblem(Obj<PETSC_MESH_TYPE> m, ufc::form * bform, ufc::form * lform){
248 _mesh = m;
249 _bform = bform;
250 _lform = lform;
251 //set up the bilinear form finite elements, and cell integral.
252 _num_finite_elements = bform->num_finite_elements();
253 _finite_elements = new ufc::finite_element *[_num_finite_elements];
254 for (int i = 0; i < _num_finite_elements; i++) {
255
256 }
257 //set up the linear form finite elements and cell integrals.
258
259 //set up the
260
261 }
262 ~UFCProblem(){};
263 //Accessors
264 void setMesh(Obj<PETSC_MESH_TYPE> m){mesh = m;}
265 Obj<PETSC_MESH_TYPE> getMesh() {return mesh;}
266 Mesh getPetscMesh() {
267 return PETSC_NULL;
268 }
269 void setForm(ufc::form * f) {form = f;}
270 ufc::form * getForm() {}
271 void setRHSFunction(ufc::function * f){rhs_funct = f;}
272 ufc::function * getRHSFunction();
273 void setExactSolution(ufc::function * f) {exact_solution = f;}
274 ufc::function * getExactSolution() {
275 return exact_solution;
276 }
277
278
279 //Misc
280 void setupUFC(){
281 //initialize the cell, function, and finite element structures for this given problem
282 finite_element = form->create_finite_element(0);
283 dof_map = form->create_dof_map(0);
284 cell_integrals = form->create_cell_integral(0);
285
286 cell = new ();
287
288 };
289 void setCell(PETSC_MESH_TYPE::point_type c) {
290
291 }
292 void setupFields(Obj<PETSC_MESH_TYPE> m, Obj<PETSC_MESH_TYPE::real_section_type> s, ufc::form form, ufc::function function){
293 setCell
294 };
295 void assembleMatrix() {
296 //use the bform to create the matrix
297
298 //partial assembly?
299 }
300 void assembleRHS() {
301 //use the lform on the interior and the bform on the boundaries to assemble the RHS
302
303 }
304 void setFieldfromFunction(Obj<PETSC_MESH_TYPE> m, Obj<PETSC_MESH_TYPE::real_section_type> s, ufc::form form, ufc::function function) {
305
306 }
307 };
308}
309
310#endif
311
312
313/*
314Wrapper to ufc::function for double * func(double * coords)
315 */
316
317class function_wrapper_scalar : public ufc::function {
318private:
319 PetscScalar (*function)(const double * coords);
320
321public:
322 void setFunction(PetscScalar (*func)(const double *)) {
323 function = func;
324 }
325 virtual void evaluate(double * values, const double * coordinates, const ufc::cell &c) const {
326 values[0] = (*function)(coordinates);
327 }
328};
329
330/*
331Do we even need this one if we're not going to be assembling ourselves?
332*/
333
334#undef __FUNCT__
335#define __FUNCT__ "Map_SieveCell_UFCCell"
336
337void Map_SieveCell_UFCCell(ALE::Obj<PETSC_MESH_TYPE> m, PETSC_MESH_TYPE::point_type c, ufc::form * form, ufc::cell * cell, const PETSC_MESH_TYPE::point_type * _oPoints = PETSC_NULL, const int _num_oPoints= -1) {
338 //set up the ufc cell to be equivalent to the sieve cell given by c; Assume that the # of dofs is constant
339 //PetscErrorCode ierr;
340
341 const ALE::Obj<PETSC_MESH_TYPE::sieve_type> s = m->getSieve();
342 ALE::Obj<PETSC_MESH_TYPE::real_section_type> coordinates = m->getRealSection("coordinates");
343 int dim = m->getDimension();
344 PetscPrintf(m->comm(), "cell of dimension: %d\n", cell->topological_dimension);
345 if ((int)cell->topological_dimension != m->getDimension() - m->height(c)) throw ALE::Exception("Wrong element dimension for this UFC form");
346 // ALE::Obj<PETSC_MESH_TYPE::oConeArray> cell_closure = PETSC_MESH_TYPE::sieve_alg_type::orientedClosure(m, m->getArrowSection("orientation"), c);
347 const PETSC_MESH_TYPE::point_type * oPoints = _oPoints;
348 int num_oPoints = _num_oPoints;
349 if (oPoints == PETSC_NULL) {
350 ALE::ISieveVisitor::PointRetriever<PETSC_MESH_TYPE::sieve_type> oC((int) pow(m->getSieve()->getMaxConeSize(), m->depth())+1, true);
351 ALE::ISieveTraversal<PETSC_MESH_TYPE::sieve_type>::orientedClosure(*s, c, oC);
352 PetscPrintf(m->comm(), "Got the orientedClosure\n");
353 oPoints = oC.getPoints();
354 num_oPoints = oC.getSize();
355 }
356
357 //PETSC_MESH_TYPE::oConeArray::iterator cc_iter = cell_closure->begin();
358 //PETSC_MESH_TYPE::oConeArray::iterator cc_iter_end = cell_closure->end();
359 int vertex_index = 0;
360
361 for (int t = 0; t < num_oPoints; t++) {
362 //PetscPrintf(PETSC_COMM_WORLD, "%d is in the closure\n", oPoints[t]);
363 //while (cc_iter != cc_iter_end) {
364 //FOR NOW: first order lagrange; if you have vertices then put 'em in. This should be ordered
365 // (and declare victory!)
366 if (m->depth(oPoints[t]) == 0) {
367 //"entities"
368 //PetscPrintf(m->comm(), "%d is vertex %d\n", cc_iter->first, vertex_index);
369 cell->entity_indices[0][vertex_index] = oPoints[t];
370 //PetscPrintf(m->comm(), "%d: ", cc_iter->first);
371 //and coordinates
372 const double * tmpcoords = coordinates->restrictPoint(oPoints[t]);
373 for (int i = 0; i < dim; i++) {
374 cell->coordinates[vertex_index][i] = tmpcoords[i];
375 }
376 vertex_index++;
377 }
378 }
379 PetscPrintf(m->comm(), "done with cell map\n");
380}
381
382
383#undef __FUNCT__
384#define __FUNCT__ "Assemble_Mat_UFC"
385
386PetscErrorCode Assemble_Mat_UFC(Mesh mesh, SectionReal section, Mat A, ufc::form * form) {
387 PetscErrorCode ierr;
388 //get, from the mesh, the assorted structures we need to do this. (numberings)
389 PetscFunctionBegin;
390
391 Obj<PETSC_MESH_TYPE::real_section_type> s;
392 ierr = SectionRealGetSection(section, s);CHKERRQ(ierr);
393
394 Obj<PETSC_MESH_TYPE> m;
395 ierr = MeshGetMesh(mesh, m);CHKERRQ(ierr);
396
397 PetscPrintf(m->comm(), "Beginning Matrix assembly.\n");
398
399 ALE::Obj<PETSC_MESH_TYPE::real_section_type> coordinates = m->getRealSection("coordinates");
400 ALE::Obj<PETSC_MESH_TYPE::label_sequence> cells = m->heightStratum(0);
401 const Obj<PETSC_MESH_TYPE::order_type>& order = m->getFactory()->getGlobalOrder(m, "default", s);
402 int dim = m->getDimension();
403
404 ufc::cell cell;
405 ufc::finite_element * finite_element = form->create_finite_element(0);
406
407 //initialize the ufc infrastructure
408 cell.geometric_dimension = dim; //might be different; check the fiberdimension of the coordinates
409 cell.topological_dimension = dim;
410 cell.entity_indices = new unsigned int *[dim+1];
411 cell.entity_indices[0] = new unsigned int[dim+1];
412 double * tmpcellcoords = new double [(dim+1)*dim];
413 int space_dimension = finite_element->space_dimension();
414 //allow both our functions and theirs to use it!
415 double * localTensor = new double[space_dimension*space_dimension];
416 //double ** localTensor = new double*[space_dimension];
417 //for(int i = 0; i < space_dimension; i++) {
418 // localTensor[i] = &localTensor_pointer[space_dimension*i];
419 //}
420 cell.coordinates = new double *[dim+1];
421
422 for (int i = 0; i < dim+1; i++) {
423 cell.coordinates[i] = &tmpcellcoords[i*dim];
424 }
425 ufc::cell_integral** cell_integrals;
426 cell_integrals = new ufc::cell_integral*[form->num_cell_integrals()];
427 if (form->num_cell_integrals() <= 0) throw ALE::Exception("Number of cell integrals in UFC form is 0.");
428 for (unsigned int i = 0; i < form->num_cell_integrals(); i++){
429 cell_integrals[i] = form->create_cell_integral(i);
430 }
431 ierr = MatZeroEntries(A);CHKERRQ(ierr);
432 PETSC_MESH_TYPE::label_sequence::iterator c_iter = cells->begin();
433 PETSC_MESH_TYPE::label_sequence::iterator c_iter_end = cells->end();
434 while (c_iter != c_iter_end) {
435 Map_SieveCell_UFCCell(m, *c_iter, form, &cell);
436 //for now just do the first cell integral. Fix when you talk to someone about what exactly having more than one means.
437 //todo: coefficients.... ask if they're global and if yes ask why.
438 cell_integrals[0]->tabulate_tensor(localTensor, (double * const *)PETSC_NULL, cell);
439 //see what the local tensor coming out looks like:
440 if (1) {
441 //maybe print the local tensor?
442 }
443 ierr = updateOperator(A, m, s, order, *c_iter, localTensor, ADD_VALUES);CHKERRQ(ierr);
444 c_iter++;
445 }
446 MatAssemblyBegin(A, MAT_FINAL_ASSEMBLY);
447 MatAssemblyEnd(A, MAT_FINAL_ASSEMBLY);
448 if (1) {
449 ierr = MatView(A, PETSC_VIEWER_STDOUT_WORLD);CHKERRQ(ierr);
450 }
451 //throw ALE::Exception("Finished the jacobian assembly for UFC; aborting for now in case it's messed up.");
452 PetscFunctionReturn(0);
453}
454
455
456#if 0
457//GET THE NEW RHS_UNSTRUCTURED FOR THIS
458
459
460PetscErrorCode Assemble_RHS_UFC(Mesh mesh, ufc::form * bform, ufc::form * lform, SectionReal X, SectionReal section, PetscScalar (*exactFunc)(const double *)) {
461 Obj<PETSC_MESH_TYPE> m;
462 PetscErrorCode ierr;
463
464 PetscFunctionBegin;
465 ierr = MeshGetMesh(mesh, m);CHKERRQ(ierr);
466
467 //const Obj<PETSC_MESH_TYPE::real_section_type>& coordinates = m->getRealSection("coordinates");
468 const Obj<PETSC_MESH_TYPE::label_sequence>& cells = m->heightStratum(0);
469 const int dim = m->getDimension();
470 ufc::finite_element * finite_element = lform->create_finite_element(0);
471 ufc::cell cell;
472 cell.geometric_dimension = dim;
473 cell.topological_dimension = dim;
474 cell.entity_indices = new unsigned int *[dim+1];
475 cell.entity_indices[0] = new unsigned int[dim];
476 cell.coordinates = new double *[dim+1];
477 double * tmpcellcoords = new double[dim*(dim+1)];
478 for (int i = 0; i < dim+1; i++) {
479 cell.coordinates[i] = &tmpcellcoords[i*dim];
480 }
481 ufc::cell_integral** cell_integrals;
482 cell_integrals = new ufc::cell_integral*[bform->num_cell_integrals()];
483 if (bform->num_cell_integrals() <= 0) throw ALE::Exception("Number of cell integrals in UFC form is 0.");
484 for (unsigned int i = 0; i < bform->num_cell_integrals(); i++){
485 cell_integrals[i] = bform->create_cell_integral(i);
486 }
487
488 ufc::cell_integral** cell_integrals_linear = new ufc::cell_integral*[lform->num_cell_integrals()];
489 for (unsigned int i = 0; i < lform->num_cell_integrals(); i++) {
490 cell_integrals_linear[i] = lform->create_cell_integral(i);
491 }
492
493 const int numBasisFuncs = finite_element->space_dimension();
494
495 //double *t_der, *b_der, *coords, *v0, *J, *invJ, detJ;
496 PetscScalar *elemVec, *elemMat;
497
498 ierr = SectionRealZero(section);CHKERRQ(ierr);
499 ierr = PetscMalloc2(numBasisFuncs,PetscScalar,&elemVec,numBasisFuncs*numBasisFuncs,PetscScalar,&elemMat);CHKERRQ(ierr);
500 // ierr = PetscMalloc6(dim,double,&t_der,dim,double,&b_der,dim,double,&coords,dim,double,&v0,dim*dim,double,&J,dim*dim,double,&invJ);CHKERRQ(ierr);
501 // Loop over cells
502 Obj<PETSC_MESH_TYPE::real_section_type> xSection;
503 Obj<PETSC_MESH_TYPE::real_section_type> fSection;
504 int c = 0;
505 double ** w = new double *[lform->num_coefficients()];
506 function_wrapper_scalar sf;
507 sf.setFunction(exactFunc);
508
509 for(PETSC_MESH_TYPE::label_sequence::iterator c_iter = cells->begin(); c_iter != cells->end(); ++c_iter, ++c) {
510 ierr = PetscMemzero(elemVec, numBasisFuncs * sizeof(PetscScalar));CHKERRQ(ierr);
511 ierr = PetscMemzero(elemMat, numBasisFuncs*numBasisFuncs * sizeof(PetscScalar));CHKERRQ(ierr);
512 //set up the weight vector to be 0.
513 //three steps for this:
514
515 //build B in the finite element space
516 // involves calling the
517 //construct A local to the boundary
518 //subtract AX from the boundary
519
520 //create the "neumann" RHS and put it in the vector
521 //m->computeElementGeometry(coordinates, *c_iter, v0, J, invJ, detJ);
522 Map_SieveCell_UFCCell(m, *c_iter, bform, &cell);
523
524 PetscScalar *x;
525
526 ierr = SectionRealRestrict(X, *c_iter, &x);CHKERRQ(ierr);
527
528 for (int f = 0; f < numBasisFuncs; f++) {
529 elemVec[f] = 0. - finite_element->evaluate_dof(f, sf, cell);
530 //PetscPrintf(m->comm(), "Elemvec[f](before): %f\n", elemVec[f]);
531 }
532 for(unsigned int i = 0; i < lform->num_coefficients(); i++) {
533 w[i] = new double[numBasisFuncs];
534 for (int j = 0; j < numBasisFuncs; j++){
535 w[i][j] = elemVec[j];
536 }
537 }
538
539 cell_integrals_linear[0]->tabulate_tensor(elemVec, w, cell);
540 cell_integrals[0]->tabulate_tensor(elemMat, w, cell);
541
542 for(int f = 0; f < numBasisFuncs; ++f) {
543 for(int g = 0; g < numBasisFuncs; ++g) {
544 elemVec[f] += elemMat[f*numBasisFuncs+g]*x[g];
545 }
546 //PetscPrintf(m->comm(), "x[f]: %f\n", x[f]);
547 //PetscPrintf(m->comm(), "elemVec[f]: %f\n", elemVec[f]);
548 }
549 ierr = SectionRealUpdateAdd(section, *c_iter, elemVec);
550 //m->updateAdd(fSection, c, elemVec);
551 }
552 ierr = PetscFree2(elemVec,elemMat);CHKERRQ(ierr);
553 //ierr = PetscFree6(t_der,b_der,coords,v0,J,invJ);CHKERRQ(ierr);
554 // Exchange neighbors
555 ierr = SectionRealComplete(section);CHKERRQ(ierr);
556 // Subtract the constant
557 if (m->hasRealSection("constant")) {
558 const Obj<PETSC_MESH_TYPE::real_section_type>& constant = m->getRealSection("constant");
559 Obj<PETSC_MESH_TYPE::real_section_type> s;
560
561 ierr = SectionRealGetSection(section, s);CHKERRQ(ierr);
562 s->axpy(-1.0, constant);
563 }
564 PetscFunctionReturn(0);
565}
566
567#endif
568
569
570PetscErrorCode Assemble_RHS_UFC(Mesh mesh, ufc::form * bform, ufc::form * lform, SectionReal X, SectionReal section, PetscScalar (*exactFunc)(const double *)) {
571
572 Obj<PETSC_MESH_TYPE> m;
573 PetscErrorCode ierr;
574
575 PetscFunctionBegin;
576 ierr = MeshGetMesh(mesh, m);CHKERRQ(ierr);
577 const Obj<ALE::Discretization>& disc = m->getDiscretization("u");
578 const Obj<PETSC_MESH_TYPE::label_sequence>& cells = m->heightStratum(0);
579 const int dim = m->getDimension();
580 PetscScalar *elemVec, *elemMat;
581
582 ufc::finite_element * finite_element = lform->create_finite_element(0);
583 ufc::cell cell;
584 cell.geometric_dimension = dim;
585 cell.topological_dimension = dim;
586 cell.entity_indices = new unsigned int *[dim+1];
587 cell.entity_indices[0] = new unsigned int[dim];
588 cell.coordinates = new double *[dim+1];
589 double * tmpcellcoords = new double[dim*(dim+1)];
590 for (int i = 0; i < dim+1; i++) {
591 cell.coordinates[i] = &tmpcellcoords[i*dim];
592 }
593 ufc::cell_integral** cell_integrals;
594 cell_integrals = new ufc::cell_integral*[bform->num_cell_integrals()];
595 if (bform->num_cell_integrals() <= 0) throw ALE::Exception("Number of cell integrals in UFC form is 0.");
596 for (unsigned int i = 0; i < bform->num_cell_integrals(); i++){
597 cell_integrals[i] = bform->create_cell_integral(i);
598 }
599
600 ufc::cell_integral** cell_integrals_linear = new ufc::cell_integral*[lform->num_cell_integrals()];
601 for (unsigned int i = 0; i < lform->num_cell_integrals(); i++) {
602 cell_integrals_linear[i] = lform->create_cell_integral(i);
603 }
604 double ** w = new double *[lform->num_coefficients()];
605 function_wrapper_scalar sf;
606 sf.setFunction(exactFunc);
607 const int numBasisFuncs = finite_element->space_dimension();
608
609
610 ierr = SectionRealZero(section);CHKERRQ(ierr);
611 ierr = PetscMalloc2(numBasisFuncs,PetscScalar,&elemVec,numBasisFuncs*numBasisFuncs,PetscScalar,&elemMat);CHKERRQ(ierr);
612 //ierr = PetscMalloc6(dim,double,&t_der,dim,double,&b_der,dim,double,&coords,dim,double,&v0,dim*dim,double,&J,dim*dim,double,&invJ);CHKERRQ(ierr);
613 // Loop over cells
614 for(PETSC_MESH_TYPE::label_sequence::iterator c_iter = cells->begin(); c_iter != cells->end(); ++c_iter) {
615 ierr = PetscMemzero(elemVec, numBasisFuncs * sizeof(PetscScalar));CHKERRQ(ierr);
616 ierr = PetscMemzero(elemMat, numBasisFuncs*numBasisFuncs * sizeof(PetscScalar));CHKERRQ(ierr);
617 //m->computeElementGeometry(coordinates, *c_iter, v0, J, invJ, detJ);
618 Map_SieveCell_UFCCell(m, *c_iter, bform, &cell);
619 //if (detJ <= 0.0) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE, "Invalid determinant %g for element %d", detJ, *c_iter);
620
621 PetscScalar *x;
622
623 ierr = SectionRealRestrict(X, *c_iter, &x);CHKERRQ(ierr);
624
625 for (int f = 0; f < numBasisFuncs; f++) {
626 elemVec[f] = 0. - finite_element->evaluate_dof(f, sf, cell);
627 //PetscPrintf(m->comm(), "Elemvec[f](before): %f\n", elemVec[f]);
628 }
629 for(unsigned int i = 0; i < lform->num_coefficients(); i++) {
630 w[i] = new double[numBasisFuncs];
631 for (int j = 0; j < numBasisFuncs; j++){
632 w[i][j] = elemVec[j];
633 }
634 }
635
636 cell_integrals_linear[0]->tabulate_tensor(elemVec, w, cell);
637 cell_integrals[0]->tabulate_tensor(elemMat, w, cell);
638
639 for(int f = 0; f < numBasisFuncs; ++f) {
640 for(int g = 0; g < numBasisFuncs; ++g) {
641 elemVec[f] += elemMat[f*numBasisFuncs+g]*x[g];
642 }
643 //PetscPrintf(m->comm(), "x[f]: %f\n", x[f]);
644 //PetscPrintf(m->comm(), "elemVec[f]: %f\n", elemVec[f]);
645 }
646
647 ierr = SectionRealUpdateAdd(section, *c_iter, elemVec);CHKERRQ(ierr);
648 }
649 ierr = PetscFree2(elemVec,elemMat);CHKERRQ(ierr);
650 //ierr = PetscFree6(t_der,b_der,coords,v0,J,invJ);CHKERRQ(ierr);
651 // Exchange neighbors
652 ierr = SectionRealComplete(section);CHKERRQ(ierr);
653 // Subtract the constant
654 if (m->hasRealSection("constant")) {
655 const Obj<PETSC_MESH_TYPE::real_section_type>& constant = m->getRealSection("constant");
656 Obj<PETSC_MESH_TYPE::real_section_type> s;
657
658 ierr = SectionRealGetSection(section, s);CHKERRQ(ierr);
659 s->axpy(-1.0, constant);
660 }
661 PetscFunctionReturn(0);
662}
663
664
665//Integrator function based upon a given UFC:
666//Takes a mesh, cell, and a UFC and integrate for all the unknowns on the cell
667
668
669#undef __FUNCT__
670#define __FUNCT__ "IntegrateDualBasis_UFC"
671
672PetscErrorCode IntegrateDualBasis_UFC(ALE::Obj<PETSC_MESH_TYPE> m, PETSC_MESH_TYPE::point_type c, ufc::form & f) {
673
674}
675
676//you still have to wrap this one as the fields are set up on the basis of the discretizations; you have to set up the discretization as it would be from the form, so we have to at least fill in the fiberdimension parts of the discretization type such that setupFields can do its work. This will be equivalent to the CreateProblem_gen_0 stuff that FIAT + Generator spits out.
677
678//CreateProblem_UFC
679//Takes a UFC form and generates the entire problem from it. This involves building a discretization object within the mesh corresponding to what is sent to UFC. Unfortunately UFC handles all the element/vectorish stuff on its own, but
680PetscErrorCode CreateProblem_UFC(DM dm, const char * name, ufc::form * form, const int numBC, const int *markers, double (**bcFuncs)(const double * coords), double(*exactFunc)(const double * coords)) {
681 Mesh mesh = (Mesh) dm;
682 ALE::Obj<PETSC_MESH_TYPE> m;
683 PetscErrorCode ierr = 0;
684 //you need some finite element information from the form.
685 ufc::finite_element * finite_element = form->create_finite_element(0);
686 //needed information from the form.
687 PetscFunctionBegin;
688 ierr = MeshGetMesh(mesh, m);CHKERRQ(ierr);
689 //int dim = m->getDimension();
690 const ALE::Obj<ALE::Discretization>& d = new ALE::Discretization(m->comm(), m->debug()); //create the UFC
691 //for now handle only vertex unknowns; complain about the fact that Dofs per dimension isn't in the release version of UFC.
692 d->setNumDof(0, 1);
693 /*
694 for (int i = 0; i < dim+1; i++) {
695 //for each element level; find the fiberdimension from the discretization and set it in the discretization.
696 d->setNumDof(
697 }
698 */
699 d->setQuadratureSize(finite_element->space_dimension());
700 //boundary conditions
701 for (int c = 0; c < numBC; c++) {
702 const ALE::Obj<ALE::BoundaryCondition>& b = new ALE::BoundaryCondition(m->comm(), m->debug());
703 ostringstream n;
704 b->setLabelName("marker");
705 b->setMarker(markers[c]);
706 b->setFunction(bcFuncs[c]);
707 //b->setDualIntegrator(IntegrateDualBasis_gen_2);
708 n << c;
709 d->setBoundaryCondition(n.str(), b);
710 if (exactFunc) {
711 const ALE::Obj<ALE::BoundaryCondition>& e = new ALE::BoundaryCondition(m->comm(), m->debug());
712 e->setLabelName("marker");
713 e->setFunction(exactFunc);
714 e->setDualIntegrator(PETSC_NULL); //TODO
715 d->setExactSolution(e);
716 }
717 }
718 m->setDiscretization(name, d);
719 PetscFunctionReturn(0);
720}
721
722#undef __FUNCT__
723#define __FUNCT__ "SetupDiscretization_UFC"
724
725void SetupDiscretization_UFC(ALE::Obj<PETSC_MESH_TYPE> m, ufc::form * form) {
726 ALE::Obj<PETSC_MESH_TYPE::sieve_type> s = m->getSieve();
727 //we will treat the thing arising from the UFC form as a SINGLE discretization such that the separation of forms is handled transparent of sieve;
728 //watch out if this screws up stuff involving the eventual output of a solution; we may have to reprocess or something silly like that.
729 //also, where there are multiple forms what should we do?
730 ALE::Obj<ALE::Discretization> d = m->getDiscretization("ufc_u");
731
732}
733
734//Comment: we shouldn't need to do this! Tie this in properly with the discretization object and then setupfield with noupdate; write a separate routine for setting the boundary values given a wrapped function.
735
736#undef __FUNCT__
737#define __FUNCT__ "SetupField_UFC"
738
739/*
740 This is essentially a copy of m->setupField(s) such that it can use the UFC dualintegrator from the associated form.
741 */
742
743#if 0
744
745 void SetupField_UFC(ALE::Obj<PETSC_MESH_TYPE> m, const ALE::Obj<PETSC_MESH_TYPE::real_section_type>& s, ufc::form * form, const int cellMarker = 2, const bool noUpdate = false){
746
747 const ALE::Obj<PETSC_MESH_TYPE::names_type>& discs = m->getDiscretizations();
748 const int debug = s->debug();
749 PETSC_MESH_TYPE::names_type bcLabels;
750 int maxDof;
751
752 //setup the necessary UFC structures here
753 ufc::finite_element * finite_element = form->create_finite_element(0);
754 function_wrapper_scalar sf;
755 ufc::cell cell;
756 int dim = m->getDimension();
757 int embeddim = m->getRealSection("coordinates")->getFiberDimension(*m->depthStratum(0)->begin());
758 cell.geometric_dimension = embeddim;
759 cell.topological_dimension = dim;
760 cell.entity_indices = new unsigned int *[dim+1];
761 cell.entity_indices[0] = new unsigned int[dim];
762 cell.coordinates = new double *[dim+1];
763
764 double * coordpointer = new double[(dim+1)*dim];
765 for (int i = 0; i < dim+1; i++) {
766 cell.coordinates[i] = &coordpointer[dim*i];
767 }
768
769 s->setChart(m->getSieve()->getChart());
770 PetscPrintf(m->comm(), "Set the chart\n");
771 maxDof = m->setFiberDimensions(s, discs, bcLabels);
772 PetscPrintf(m->comm(), "Set the max dof\n");
773 m->calculateIndices();
774 PetscPrintf(m->comm(), "Calculated the indices\n");
775 m->calculateIndicesExcluded(s, discs);
776 PetscPrintf(m->comm(), "Calculated the excluded indices\n");
777 m->allocate(s);
778 PetscPrintf(m->comm(), "Allocated\n");
779 s->defaultConstraintDof();
780 PetscPrintf(m->comm(), "Set the default constraint DOF");
781 const ALE::Obj<PETSC_MESH_TYPE::label_type>& cellExclusion = m->getLabel("cellExclusion");
782 PetscPrintf(m->comm(), "Cell exclusion\n");
783 if (debug > 1) {std::cout << "Setting boundary values" << std::endl;}
784 PetscPrintf(m->comm(), "At the boundary condition loop\n");
785 for(PETSC_MESH_TYPE::names_type::const_iterator n_iter = bcLabels.begin(); n_iter != bcLabels.end(); ++n_iter) {
786 const ALE::Obj<PETSC_MESH_TYPE::label_sequence>& boundaryCells = m->getLabelStratum(*n_iter, cellMarker);
787 // const ALE::Obj<PETSC_MESH_TYPE::real_section_type>& coordinates = m->getRealSection("coordinates");
788 const ALE::Obj<PETSC_MESH_TYPE::names_type>& discs = m->getDiscretizations();
789 ALE::Obj<PETSC_MESH_TYPE::sieve_type> sieve = m->getSieve();
790 const PETSC_MESH_TYPE::point_type firstCell = *boundaryCells->begin();
791 const int numFields = discs->size();
792 PETSC_MESH_TYPE::real_section_type::value_type *values = new PETSC_MESH_TYPE::real_section_type::value_type[m->sizeWithBC(s, firstCell)];
793 int *dofs = new int[maxDof];
794 int *v = new int[numFields];
795 //double *v0 = new double[m->getDimension()];
796 //double *J = new double[m->getDimension()*m->getDimension()];
797 //double detJ;
798 ALE::ISieveVisitor::PointRetriever<PETSC_MESH_TYPE::sieve_type> oC((int) pow(m->getSieve()->getMaxConeSize(), m->depth())+1, true);
799
800 for(PETSC_MESH_TYPE::label_sequence::iterator c_iter = boundaryCells->begin(); c_iter != boundaryCells->end(); ++c_iter) {
801
802 //const Obj<PETSC_MESH_TYPE::coneArray> closure = PETSC_MESH_TYPE::sieve_alg_type::closure(m, m->getArrowSection("orientation"), *c_iter);
803 //const PETSC_MESH_TYPE::coneArray::iterator end = closure->end();
804
805 if (debug > 1) {std::cout << " Boundary cell " << *c_iter << std::endl;}
806 ALE::ISieveTraversal<PETSC_MESH_TYPE::sieve_type>::orientedClosure(sieve, *c_iter, oC);
807 const PETSC_MESH_TYPE::point_type * oPoints = oC.getPoints();
808 const int num_oPoints = oC.getSize();
809 Map_SieveCell_UFCCell(m, *c_iter, form, &cell, oPoints, num_oPoints);
810 PetscPrintf(m->comm(), "successfully quit the cell map\n");
811 //m->computeElementGeometry(coordinates, *c_iter, v0, J, PETSC_NULL, detJ);
812 for(int f = 0; f < numFields; ++f) v[f] = 0;
813 for(int t = 0; t < num_oPoints; t++) {
814 const int cDim = s->getConstraintDimension(oPoints[t]);
815 int off = 0;
816 int f = 0;
817 int i = -1;
818 if (debug > 1) {std::cout << " point " << oPoints[t] << std::endl;}
819 if (cDim) {
820 if (debug > 1) {std::cout << " constrained excMarker: " << m->getValue(cellExclusion, *c_iter) << std::endl;}
821 for(PETSC_MESH_TYPE::names_type::const_iterator f_iter = discs->begin(); f_iter != discs->end(); ++f_iter, ++f) {
822 const ALE::Obj<ALE::Discretization>& disc = m->getDiscretization(*f_iter);
823 const ALE::Obj<PETSC_MESH_TYPE::names_type> bcs = disc->getBoundaryConditions();
824 const int fDim = s->getFiberDimension(oPoints[t], f);//disc->getNumDof(m->depth(*cl_iter));
825 const int *indices = disc->getIndices(m->getValue(cellExclusion, *c_iter));
826 int b = 0;
827
828 for(PETSC_MESH_TYPE::names_type::const_iterator bc_iter = bcs->begin(); bc_iter != bcs->end(); ++bc_iter, ++b) {
829 const ALE::Obj<ALE::BoundaryCondition>& bc = disc->getBoundaryCondition(*bc_iter);
830 const int value = m->getValue(m->getLabel(bc->getLabelName()), oPoints[t]);
831
832 if (b > 0) v[f] -= fDim;
833
834 if (value == bc->getMarker()) {
835 if (debug > 1) {std::cout << " field " << *f_iter << " marker " << value << std::endl;}
836 //instead, we use the form's dual integrator (evaluation
837 sf.setFunction(bc->getFunction());
838 /*
839 for(int d = 0; d < fDim; ++d, ++v[f]) {
840 dofs[++i] = off+d;
841 if (!noUpdate) values[indices[v[f]]] = (*bc->getDualIntegrator())(v0, J, v[f], bc->getFunction());
842 if (debug > 1) {std::cout << " setting values["<<indices[v[f]]<<"] = " << values[indices[v[f]]] << std::endl;}
843 }
844 */
845
846 for (int d = 0; d < fDim; ++d, ++v[f]) {
847 dofs[++i] = off+d;
848 if (!noUpdate) {
849 values[indices[v[f]]] = finite_element->evaluate_dof(v[f], sf, cell);
850 PetscPrintf(m->comm(), "evaluated DOF %d\n", f);
851 }
852
853 }
854 ++b;
855 break;
856 } else {
857 if (debug > 1) {std::cout << " field " << *f_iter << std::endl;}
858 for(int d = 0; d < fDim; ++d, ++v[f]) {
859 values[indices[v[f]]] = 0.0;
860 if (debug > 1) {std::cout << " setting values["<<indices[v[f]]<<"] = " << values[indices[v[f]]] << std::endl;}
861 }
862 }
863 }
864 if (b == 0) {
865 if (debug > 1) {std::cout << " field " << *f_iter << std::endl;}
866 for(int d = 0; d < fDim; ++d, ++v[f]) {
867 values[indices[v[f]]] = 0.0;
868 if (debug > 1) {std::cout << " setting values["<<indices[v[f]]<<"] = " << values[indices[v[f]]] << std::endl;}
869 }
870 }
871 off += fDim;
872 }
873 if (i != cDim-1) {throw ALE::Exception("Invalid constraint initialization");}
874 s->setConstraintDof(oPoints[t], dofs);
875 } else {
876 if (debug > 1) {std::cout << " unconstrained" << std::endl;}
877 for(PETSC_MESH_TYPE::names_type::const_iterator f_iter = discs->begin(); f_iter != discs->end(); ++f_iter, ++f) {
878 const Obj<ALE::Discretization>& disc = m->getDiscretization(*f_iter);
879 const int fDim = s->getFiberDimension(oPoints[t], f);//disc->getNumDof(m->depth(*cl_iter));
880 const int *indices = disc->getIndices(m->getValue(cellExclusion, *c_iter));
881
882 if (debug > 1) {std::cout << " field " << *f_iter << std::endl;}
883 for(int d = 0; d < fDim; ++d, ++v[f]) {
884 values[indices[v[f]]] = 0.0;
885 if (debug > 1) {std::cout << " setting values["<<indices[v[f]]<<"] = " << values[indices[v[f]]] << std::endl;}
886 }
887 }
888 }
889 }
890#if 0
891 if (debug > 1) {
892 const Obj<PETSC_MESH_TYPE::sieve_type::coneArray> closure = PETSC_MESH_TYPE::sieve_alg_type::closure(m, m->getArrowSection("orientation"), *c_iter);
893 const PETSC_MESH_TYPE::sieve_type::coneArray::iterator end = closure->end();
894
895 for(int f = 0; f < numFields; ++f) v[f] = 0;
896 for(PETSC_MESH_TYPE::sieve_type::coneArray::iterator cl_iter = closure->begin(); cl_iter != end; ++cl_iter) {
897 int f = 0;
898 for(PETSC_MESH_TYPE::names_type::const_iterator f_iter = discs->begin(); f_iter != discs->end(); ++f_iter, ++f) {
899 const Obj<ALE::Discretization>& disc = m->getDiscretization(*f_iter);
900 const int fDim = s->getFiberDimension(*cl_iter, f);
901 const int *indices = disc->getIndices(m->getValue(cellExclusion, *c_iter));
902
903 for(int d = 0; d < fDim; ++d, ++v[f]) {
904 std::cout << " "<<*f_iter<<"-value["<<indices[v[f]]<<"] " << values[indices[v[f]]] << std::endl;
905 }
906 }
907 }
908 }
909#endif
910 if (!noUpdate) {
911 m->updateAll(s, *c_iter, values);
912 }
913 }
914 PetscPrintf(m->comm(), "Done with the cell loop.\n");
915 delete [] dofs;
916 delete [] values;
917 }
918 if (debug > 1) {s->view("");}
919 }
920
921#endif
922
923void SetupField_UFC(ALE::Obj<PETSC_MESH_TYPE> m, const ALE::Obj<PETSC_MESH_TYPE::real_section_type>& s, ufc::form * form, const int cellMarker = 2, const bool noUpdate = false) {
924 typedef ALE::ISieveVisitor::PointRetriever<PETSC_MESH_TYPE::sieve_type> Visitor;
925 const ALE::Obj<PETSC_MESH_TYPE::names_type>& discs = m->getDiscretizations();
926 const int debug = s->debug();
927 PETSC_MESH_TYPE::names_type bcLabels;
928
929 s->setChart(m->getSieve()->getChart());
930 int maxdof = m->setFiberDimensions(s, discs, bcLabels);
931 m->calculateIndices();
932 m->calculateIndicesExcluded(s, discs);
933 m->allocate(s);
934 s->defaultConstraintDof();
935 const ALE::Obj<PETSC_MESH_TYPE::label_type>& cellExclusion = m->getLabel("cellExclusion");
936
937 ufc::finite_element * finite_element = form->create_finite_element(0);
938 function_wrapper_scalar sf;
939 ufc::cell cell;
940 int dim = m->getDimension();
941 int embeddim = m->getRealSection("coordinates")->getFiberDimension(*m->depthStratum(0)->begin());
942 cell.geometric_dimension = embeddim;
943 cell.topological_dimension = dim;
944 cell.entity_indices = new unsigned int *[dim+1];
945 cell.entity_indices[0] = new unsigned int[dim];
946 cell.coordinates = new double *[dim+1];
947
948 double * coordpointer = new double[(dim+1)*dim];
949 for (int i = 0; i < dim+1; i++) {
950 cell.coordinates[i] = &coordpointer[dim*i];
951 }
952
953
954 if (debug > 1) {std::cout << "Setting boundary values" << std::endl;}
955 for(PETSC_MESH_TYPE::names_type::const_iterator n_iter = bcLabels.begin(); n_iter != bcLabels.end(); ++n_iter) {
956 function_wrapper_scalar sf;
957 const ALE::Obj<PETSC_MESH_TYPE::label_sequence>& boundaryCells = m->getLabelStratum(*n_iter, cellMarker);
958 const ALE::Obj<PETSC_MESH_TYPE::real_section_type>& coordinates = m->getRealSection("coordinates");
959 const ALE::Obj<PETSC_MESH_TYPE::names_type>& discs = m->getDiscretizations();
960 const PETSC_MESH_TYPE::point_type firstCell = *boundaryCells->begin();
961 const int numFields = discs->size();
962 PETSC_MESH_TYPE::real_section_type::value_type *values = new PETSC_MESH_TYPE::real_section_type::value_type[m->sizeWithBC(s, firstCell)];
963 int *dofs = new int[maxdof];
964 int *v = new int[numFields];
965 double *v0 = new double[m->getDimension()];
966 double *J = new double[m->getDimension()*m->getDimension()];
967 double detJ;
968 Visitor pV((int) pow(m->getSieve()->getMaxConeSize(), m->depth())+1, true);
969
970 for(PETSC_MESH_TYPE::label_sequence::iterator c_iter = boundaryCells->begin(); c_iter != boundaryCells->end(); ++c_iter) {
971 ALE::ISieveTraversal<PETSC_MESH_TYPE::sieve_type>::orientedClosure(*m->getSieve(), *c_iter, pV);
972 const Visitor::point_type *oPoints = pV.getPoints();
973 const int oSize = pV.getSize();
974
975 if (debug > 1) {std::cout << " Boundary cell " << *c_iter << std::endl;}
976 m->computeElementGeometry(coordinates, *c_iter, v0, J, PETSC_NULL, detJ);
977 for(int f = 0; f < numFields; ++f) v[f] = 0;
978 for(int cl = 0; cl < oSize; ++cl) {
979 const int cDim = s->getConstraintDimension(oPoints[cl]);
980 int off = 0;
981 int f = 0;
982 int i = -1;
983
984 if (debug > 1) {std::cout << " point " << oPoints[cl] << std::endl;}
985 if (cDim) {
986 if (debug > 1) {std::cout << " constrained excMarker: " << m->getValue(cellExclusion, *c_iter) << std::endl;}
987 for(PETSC_MESH_TYPE::names_type::const_iterator f_iter = discs->begin(); f_iter != discs->end(); ++f_iter, ++f) {
988 const Obj<ALE::Discretization>& disc = m->getDiscretization(*f_iter);
989 const Obj<PETSC_MESH_TYPE::names_type> bcs = disc->getBoundaryConditions();
990 const int fDim = s->getFiberDimension(oPoints[cl], f);//disc->getNumDof(this->depth(oPoints[cl]));
991 const int *indices = disc->getIndices(m->getValue(cellExclusion, *c_iter));
992 int b = 0;
993
994 for(PETSC_MESH_TYPE::names_type::const_iterator bc_iter = bcs->begin(); bc_iter != bcs->end(); ++bc_iter, ++b) {
995 const Obj<ALE::BoundaryCondition>& bc = disc->getBoundaryCondition(*bc_iter);
996 const int value = m->getValue(m->getLabel(bc->getLabelName()), oPoints[cl]);
997 sf.setFunction(bc->getFunction());
998 if (b > 0) v[f] -= fDim;
999 if (value == bc->getMarker()) {
1000 if (debug > 1) {std::cout << " field " << *f_iter << " marker " << value << std::endl;}
1001 for (int d = 0; d < fDim; ++d, ++v[f]) {
1002 dofs[++i] = off+d;
1003 if (!noUpdate) {
1004 values[indices[v[f]]] = finite_element->evaluate_dof(v[f], sf, cell);
1005 PetscPrintf(m->comm(), "evaluated DOF %d\n", f);
1006 }
1007 }
1008 /*
1009 for(int d = 0; d < fDim; ++d, ++v[f]) {
1010 dofs[++i] = off+d;
1011 if (!noUpdate) values[indices[v[f]]] = (*bc->getDualIntegrator())(v0, J, v[f], bc->getFunction());
1012 if (debug > 1) {std::cout << " setting values["<<indices[v[f]]<<"] = " << values[indices[v[f]]] << std::endl;}
1013 }
1014 */
1015 // Allow only one condition per point
1016 ++b;
1017 break;
1018 } else {
1019 if (debug > 1) {std::cout << " field " << *f_iter << std::endl;}
1020 for(int d = 0; d < fDim; ++d, ++v[f]) {
1021 values[indices[v[f]]] = 0.0;
1022 if (debug > 1) {std::cout << " setting values["<<indices[v[f]]<<"] = " << values[indices[v[f]]] << std::endl;}
1023 }
1024 }
1025 }
1026 if (b == 0) {
1027 if (debug > 1) {std::cout << " field " << *f_iter << std::endl;}
1028 for(int d = 0; d < fDim; ++d, ++v[f]) {
1029 values[indices[v[f]]] = 0.0;
1030 if (debug > 1) {std::cout << " setting values["<<indices[v[f]]<<"] = " << values[indices[v[f]]] << std::endl;}
1031 }
1032 }
1033 off += fDim;
1034 }
1035 if (i != cDim-1) {throw ALE::Exception("Invalid constraint initialization");}
1036 s->setConstraintDof(oPoints[cl], dofs);
1037 } else {
1038 if (debug > 1) {std::cout << " unconstrained" << std::endl;}
1039 for(PETSC_MESH_TYPE::names_type::const_iterator f_iter = discs->begin(); f_iter != discs->end(); ++f_iter, ++f) {
1040 const Obj<ALE::Discretization>& disc = m->getDiscretization(*f_iter);
1041 const int fDim = s->getFiberDimension(oPoints[cl], f);//disc->getNumDof(this->depth(oPoints[cl]));
1042 const int *indices = disc->getIndices(m->getValue(cellExclusion, *c_iter));
1043
1044 if (debug > 1) {std::cout << " field " << *f_iter << std::endl;}
1045 for(int d = 0; d < fDim; ++d, ++v[f]) {
1046 values[indices[v[f]]] = 0.0;
1047 if (debug > 1) {std::cout << " setting values["<<indices[v[f]]<<"] = " << values[indices[v[f]]] << std::endl;}
1048 }
1049 }
1050 }
1051 }
1052 if (debug > 1) {
1053 for(int f = 0; f < numFields; ++f) v[f] = 0;
1054 for(int cl = 0; cl < oSize; ++cl) {
1055 int f = 0;
1056 for(PETSC_MESH_TYPE::names_type::const_iterator f_iter = discs->begin(); f_iter != discs->end(); ++f_iter, ++f) {
1057 const Obj<ALE::Discretization>& disc = m->getDiscretization(*f_iter);
1058 const int fDim = s->getFiberDimension(oPoints[cl], f);
1059 const int *indices = disc->getIndices(m->getValue(cellExclusion, *c_iter));
1060
1061 for(int d = 0; d < fDim; ++d, ++v[f]) {
1062 std::cout << " "<<*f_iter<<"-value["<<indices[v[f]]<<"] " << values[indices[v[f]]] << std::endl;
1063 }
1064 }
1065 }
1066 }
1067 if (!noUpdate) {
1068 m->updateAll(s, *c_iter, values);
1069 }
1070 pV.clear();
1071 }
1072 delete [] dofs;
1073 delete [] values;
1074 delete [] v0;
1075 delete [] J;
1076 }
1077 if (debug > 1) {s->view("");}
1078}
1079
1080
1081#undef __FUNCT__
1082#define __FUNCT__ "CreateExactSolution_UFC"
1083 PetscErrorCode CreateExactSolution_UFC(Obj<PETSC_MESH_TYPE> m, Obj<PETSC_MESH_TYPE::real_section_type> s, ufc::form * form, PetscScalar (*exactSolution)(const double *))
1084 {
1085 const int dim = m->getDimension();
1086 //PetscBool flag;
1087 //PetscErrorCode ierr;
1088
1089 PetscFunctionBegin;
1090 SetupField_UFC(m, s, form);
1091 ufc::finite_element * finite_element = form->create_finite_element(0);
1092 ufc::cell cell;
1093 cell.geometric_dimension = dim;
1094 cell.topological_dimension = dim;
1095 cell.entity_indices = new unsigned int *[dim+1];
1096 cell.entity_indices[0] = new unsigned int[dim];
1097 cell.coordinates = new double *[dim+1];
1098 double * tmpcellcoords = new double[dim*(dim+1)];
1099 for (int i = 0; i < dim+1; i++) {
1100 cell.coordinates[i] = &tmpcellcoords[i*dim];
1101 }
1102 const Obj<PETSC_MESH_TYPE::label_sequence>& cells = m->heightStratum(0);
1103 //const Obj<PETSC_MESH_TYPE::real_section_type>& coordinates = m->getRealSection("coordinates");
1104 const int localDof = m->sizeWithBC(s, *cells->begin());
1105 PETSC_MESH_TYPE::real_section_type::value_type *values = new PETSC_MESH_TYPE::real_section_type::value_type[localDof];
1106 function_wrapper_scalar sf;
1107 sf.setFunction(exactSolution);
1108 for(PETSC_MESH_TYPE::label_sequence::iterator c_iter = cells->begin(); c_iter != cells->end(); ++c_iter) {
1109 const Obj<PETSC_MESH_TYPE::coneArray> closure = ALE::SieveAlg<ALE::Mesh>::closure(m, *c_iter);
1110 const PETSC_MESH_TYPE::coneArray::iterator end = closure->end();
1111 int v = 0;
1112
1113 //m->computeElementGeometry(coordinates, *c_iter, v0, J, PETSC_NULL, detJ);
1114 Map_SieveCell_UFCCell(m, *c_iter, form, &cell);
1115 for(PETSC_MESH_TYPE::coneArray::iterator cl_iter = closure->begin(); cl_iter != end; ++cl_iter) {
1116 const int pointDim = s->getFiberDimension(*cl_iter);
1117 //FOR NOW: keep this, only get rid of the integration routine.
1118 if (pointDim) {
1119 for(int d = 0; d < pointDim; ++d, ++v) {
1120 values[v] = finite_element->evaluate_dof(v, sf, cell);
1121 //values[v] = (*options->integrate)(v0, J, v, options->exactFunc);
1122 }
1123 }
1124 }
1125 m->updateAll(s, *c_iter, values);
1126 }
1127 s->view("setup field");
1128 PetscFunctionReturn(0);
1129 }
1130
Note: See TracBrowser for help on using the repository browser.