//----------------------------------------------------------------------------- std::map<std::size_t, std::size_t> Extrapolation::compute_unique_dofs(const Cell& cell, const FunctionSpace& V, std::size_t& row, std::set<std::size_t>& unique_dofs) { dolfin_assert(V.dofmap()); const ArrayView<const dolfin::la_index> dofs = V.dofmap()->cell_dofs(cell.index()); // Data structure for current cell std::map<std::size_t, std::size_t> dof2row; for (std::size_t i = 0; i < V.dofmap()->num_element_dofs(cell.index()); ++i) { // Ignore if this degree of freedom is already considered if (unique_dofs.find(dofs[i]) != unique_dofs.end()) continue; // Put global index into unique_dofs unique_dofs.insert(dofs[i]); // Map local dof index to current matrix row-index dof2row[i] = row; // Increase row index row++; } return dof2row; }
void Prolongation(const FunctionSpace& V, const Array<double>& Gx, const Array<double>& Gy, const Array<double>& Gz, double * dataX, double * dataY, double * dataZ) { const Mesh mesh = *V.mesh(); const GenericDofMap& dofmap_u = *V.dofmap(); const int n = mesh.num_cells(); const int m = mesh.num_edges(); std::vector<int> edge2dof; edge2dof.reserve(m); Cell* dolfin_cell; for (int i = 0; i < n; ++i) { dolfin_cell = new Cell(mesh, i); std::vector<int> cellDOF = dofmap_u.cell_dofs(i); const uint* edgeVALUES = dolfin_cell->entities(1); for (int j = 0; j < cellDOF.size(); ++j) { edge2dof[edgeVALUES[j]]=cellDOF[j]; } } Edge* dolfin_edge; int k = -1; for (int i = 0; i < m; ++i) { k = k + 1; dolfin_edge = new Edge(mesh, i); dataX[k] =Gx[dolfin_edge->index()]/2; dataY[k] =Gy[dolfin_edge->index()]/2; dataZ[k] =Gz[dolfin_edge->index()]/2; k = k + 1; dataX[k] =Gx[dolfin_edge->index()]/2; dataY[k] =Gy[dolfin_edge->index()]/2; dataZ[k] =Gz[dolfin_edge->index()]/2; } }
//----------------------------------------------------------------------------- DirichletBC::LocalData::LocalData(const FunctionSpace& V) : w(V.dofmap()->max_element_dofs(), 0.0), facet_dofs(V.dofmap()->num_facet_dofs(), 0), coordinates(boost::extents[V.dofmap()->max_element_dofs()][V.mesh()->geometry().dim()]) { // Do nothing }
Probes::Probes(const Array<double>& x, const FunctionSpace& V) { const std::size_t Nd = V.mesh()->geometry().dim(); const std::size_t N = x.size() / Nd; Array<double> _x(Nd); total_number_probes = N; _value_size = 1; _num_evals = 0; for (std::size_t i = 0; i < V.element()->value_rank(); i++) _value_size *= V.element()->value_dimension(i); for (std::size_t i=0; i<N; i++) { for (std::size_t j=0; j<Nd; j++) _x[j] = x[i*Nd + j]; try { Probe* probe = new Probe(_x, V); std::pair<std::size_t, Probe*> newprobe = std::make_pair(i, &(*probe)); _allprobes.push_back(newprobe); } catch (std::exception &e) { // do-nothing } } //cout << _allprobes.size() << " of " << N << " probes found on processor " << MPI::process_number() << endl; }
//----------------------------------------------------------------------------- SubSpace::SubSpace(const FunctionSpace& V, const std::vector<std::size_t>& component) : FunctionSpace(V.mesh(), V.element(), V.dofmap()) { // Extract subspace and assign std::shared_ptr<FunctionSpace> _function_space(V.extract_sub_space(component)); *static_cast<FunctionSpace*>(this) = *_function_space; }
Probe::Probe(const Array<double>& x, const FunctionSpace& V) : _element(V.element()), _num_evals(0) { const Mesh& mesh = *V.mesh(); std::size_t gdim = mesh.geometry().dim(); // Find the cell that contains probe const Point point(gdim, x.data()); unsigned int cell_id = mesh.bounding_box_tree()->compute_first_entity_collision(point); // If the cell is on this process, then create an instance // of the Probe class. Otherwise raise a dolfin_error. if (cell_id != std::numeric_limits<unsigned int>::max()) { // Store position of probe for (std::size_t i = 0; i < 3; i++) _x[i] = (i < gdim ? x[i] : 0.0); // Compute in tensor (one for scalar function, . . .) _value_size_loc = 1; for (std::size_t i = 0; i < _element->value_rank(); i++) _value_size_loc *= _element->value_dimension(i); _probes.resize(_value_size_loc); // Create cell that contains point dolfin_cell.reset(new Cell(mesh, cell_id)); dolfin_cell->get_cell_data(ufc_cell); coefficients.resize(_element->space_dimension()); // Cell vertices dolfin_cell->get_vertex_coordinates(vertex_coordinates); // Create work vector for basis basis_matrix.resize(_value_size_loc); for (std::size_t i = 0; i < _value_size_loc; ++i) basis_matrix[i].resize(_element->space_dimension()); std::vector<double> basis(_value_size_loc); const int cell_orientation = 0; for (std::size_t i = 0; i < _element->space_dimension(); ++i) { _element->evaluate_basis(i, &basis[0], &x[0], vertex_coordinates.data(), cell_orientation); for (std::size_t j = 0; j < _value_size_loc; ++j) basis_matrix[j][i] = basis[j]; } } else { dolfin_error("Probe.cpp","set probe","Probe is not found on processor"); } }
//----------------------------------------------------------------------------- void PointSource::check_is_scalar(const FunctionSpace& V) { dolfin_assert(V.element()); if (V.element()->value_rank() != 0) { dolfin_error("PointSource.cpp", "create point source", "Function is not scalar"); } }
//----------------------------------------------------------------------------- SubSpace::SubSpace(const FunctionSpace& V, std::size_t component, std::size_t sub_component) : FunctionSpace(V.mesh(), V.element(), V.dofmap()) { // Create array std::vector<std::size_t> c = {{component, sub_component}}; // Extract subspace and assign std::shared_ptr<FunctionSpace> _function_space(V.extract_sub_space(c)); *static_cast<FunctionSpace*>(this) = *_function_space; }
//----------------------------------------------------------------------------- Function::Function(const FunctionSpace& V, std::string filename) : Hierarchical<Function>(*this), _function_space(reference_to_no_delete_pointer(V)), _allow_extrapolation(dolfin::parameters["allow_extrapolation"]) { // Check that we don't have a subspace if (!V.component().empty()) { dolfin_error("Function.cpp", "create function", "Cannot be created from subspace. Consider collapsing the function space"); } // Initialize vector init_vector(); // Check size of vector if (_vector->size() != _function_space->dim()) { dolfin_error("Function.cpp", "read function from file", "The number of degrees of freedom (%d) does not match dimension of function space (%d)", _vector->size(), _function_space->dim()); } // Read function data from file File file(filename); file >> *this; }
void Interpolator<double>:: interpolate(const MElement& element, const FunctionSpace& fs, const std::vector<double>& coef, const fullVector<double>& xyz, fullVector<double>& value){ // Scalar or Vector ? const bool isScalar = fs.isScalar(); if(isScalar){ // Function Space Scalar const FunctionSpaceScalar* fsScalar = static_cast<const FunctionSpaceScalar*>(&fs); // Alloc value value.resize(1); // Interpolate value(0) = fsScalar->interpolate(element, coef, xyz); } else{ // Function Space Vector const FunctionSpaceVector* fsVector = static_cast<const FunctionSpaceVector*>(&fs); // Alloc & Interpolate value = fsVector->interpolate(element, coef, xyz); } }
//----------------------------------------------------------------------------- void Extrapolation::build_unique_dofs( std::set<std::size_t>& unique_dofs, std::map<std::size_t, std::map<std::size_t, std::size_t>>& cell2dof2row, const Cell& cell0, const FunctionSpace& V) { // Counter for matrix row index std::size_t row = 0; dolfin_assert(V.mesh()); // Get unique set of surrounding cells (including cell0) std::set<std::size_t> cell_set; for (VertexIterator vtx(cell0); !vtx.end(); ++vtx) { for (CellIterator cell1(*vtx); !cell1.end(); ++cell1) cell_set.insert(cell1->index()); } // Compute unique dofs on patch for (auto cell_it : cell_set) { Cell cell1(cell0.mesh(), cell_it); cell2dof2row[cell_it] = compute_unique_dofs(cell1, V, row, unique_dofs); } }
DDMContextOSRCVector:: DDMContextOSRCVector(const GroupOfElement& domain, vector<const GroupOfElement*>& dirichlet, const FunctionSpace& fSpace, const FunctionSpace& fSpaceG, const vector<const FunctionSpaceVector*>& phi, const vector<const FunctionSpaceScalar*>& rho, const FunctionSpaceVector& r, double k, Complex keps, int NPade, double theta){ // Check if vector // if(fSpace.isScalar()) throw Exception("DDMContextOSRCVector: need a vector function space"); // Data for OSRCVector // this->domain = &domain; this->fSpace = &fSpace; this->fSpaceG = &fSpaceG; this->dirichlet = dirichlet; this->phi = φ this->rho = ρ this->r = &r; this->NPade = NPade; this->theta = theta; this->k = k; this->keps = keps; }
void Probes::add_positions(const Array<double>& x, const FunctionSpace& V) { const std::size_t gdim = V.mesh()->geometry().dim(); const std::size_t N = x.size() / gdim; Array<double> _x(gdim); const std::size_t old_N = total_number_probes; const std::size_t old_local_size = local_size(); total_number_probes += N; for (std::size_t i=0; i<N; i++) { for (std::size_t j=0; j<gdim; j++) _x[j] = x[i*gdim + j]; try { Probe* probe = new Probe(_x, V); std::pair<std::size_t, Probe*> newprobe = std::make_pair(old_N+i, &(*probe)); _allprobes.push_back(newprobe); } catch (std::exception &e) { // do-nothing } } //cout << local_size() - old_local_size << " of " << N << " probes found on processor " << MPI::process_number() << endl; }
void Interpolator<Complex>:: interpolate(const MElement& element, const FunctionSpace& fs, const std::vector<Complex>& coef, const fullVector<double>& xyz, fullVector<Complex>& value){ // Real & Imaginary // const size_t size = coef.size(); vector<double> coefReal(size); vector<double> coefImag(size); for(size_t i = 0; i < size; i++) coefReal[i] = coef[i].real(); for(size_t i = 0; i < size; i++) coefImag[i] = coef[i].imag(); // Scalar or Vector ? const bool isScalar = fs.isScalar(); if(isScalar){ // Function Space Scalar const FunctionSpaceScalar* fsScalar = static_cast<const FunctionSpaceScalar*>(&fs); // Alloc value value.resize(1); // Interpolate double real = fsScalar->interpolate(element, coefReal, xyz); double imag = fsScalar->interpolate(element, coefImag, xyz); // Complex value(0) = Complex(real, imag); } else{ // Function Space Vector const FunctionSpaceVector* fsVector = static_cast<const FunctionSpaceVector*>(&fs); // Alloc value value.resize(3); // Interpolate fullVector<double> real = fsVector->interpolate(element, coefReal, xyz); fullVector<double> imag = fsVector->interpolate(element, coefImag, xyz); // Complex value(0) = Complex(real(0), imag(0)); value(1) = Complex(real(1), imag(1)); value(2) = Complex(real(2), imag(2)); } }
void Gradient(const FunctionSpace& V, const Array<int>& Mapping, double * column, double * row, double * data) { const Mesh mesh = *V.mesh(); const GenericDofMap& dofmap_u = *V.dofmap(); const int n = mesh.num_cells(); const int m = mesh.num_edges(); std::vector<int> edge2dof; edge2dof.reserve(m); Cell* dolfin_cell; for (int i = 0; i < n; ++i) { dolfin_cell = new Cell(mesh, i); std::vector<int> cellDOF = dofmap_u.cell_dofs(i); const uint* edgeVALUES = dolfin_cell->entities(1); for (int j = 0; j < cellDOF.size(); ++j) { edge2dof[edgeVALUES[j]]=cellDOF[j]; } } Edge* dolfin_edge; int k = -1; for (int i = 0; i < m; ++i) { dolfin_edge = new Edge(mesh, i); const uint* edgeVERTICES = dolfin_edge->entities(0); k = k+1; row[k]=edge2dof[dolfin_edge->index()]; column[k]=Mapping[edgeVERTICES[0]]; data[k]=-1; k = k+1; row[k]=edge2dof[dolfin_edge->index()]; column[k]=Mapping[edgeVERTICES[1]]; data[k]=1; } }
//----------------------------------------------------------------------------- void Extrapolation::build_unique_dofs(std::set<std::size_t>& unique_dofs, std::map<std::size_t, std::map<std::size_t, std::size_t> >& cell2dof2row, const Cell& cell0, const ufc::cell& c0, const FunctionSpace& V) { // Counter for matrix row index std::size_t row = 0; dolfin_assert(V.mesh()); UFCCell c1(*V.mesh()); // Compute unique dofs on center cell cell2dof2row[cell0.index()] = compute_unique_dofs(cell0, c0, V, row, unique_dofs); // Compute unique dofs on neighbouring cells for (CellIterator cell1(cell0); !cell1.end(); ++cell1) { c1.update(*cell1); cell2dof2row[cell1->index()] = compute_unique_dofs(*cell1, c1, V, row, unique_dofs); } }
void FormulationHelper::initDofMap(const FunctionSpace& fs, const GroupOfElement& goe, map<Dof, Complex>& data){ // Get Keys from goe // set<Dof> dSet; fs.getKeys(goe, dSet); // Insert Dofs in data // set<Dof>::iterator it = dSet.begin(); set<Dof>::iterator end = dSet.end(); for(; it != end; it++) data.insert(pair<Dof, Complex>(*it, 0)); }
StatisticsProbes::StatisticsProbes(const Array<double>& x, const FunctionSpace& V, bool segregated) { const std::size_t Nd = V.mesh()->geometry().dim(); const std::size_t N = x.size() / Nd; Array<double> _x(Nd); total_number_probes = N; _num_evals = 0; _value_size = 1; for (std::size_t i = 0; i < V.element()->value_rank(); i++) _value_size *= V.element()->value_dimension(i); if (segregated) { assert(V.element()->value_rank() == 0); _value_size *= V.element()->geometric_dimension(); } // Symmetric statistics. Velocity: u, v, w, uu, vv, ww, uv, uw, vw _value_size = _value_size*(_value_size+3)/2.; for (std::size_t i=0; i<N; i++) { for (std::size_t j=0; j<Nd; j++) _x[j] = x[i*Nd + j]; try { StatisticsProbe* probe = new StatisticsProbe(_x, V, segregated); std::pair<std::size_t, StatisticsProbe*> newprobe = std::make_pair(i, &(*probe)); _allprobes.push_back(newprobe); } catch (std::exception &e) { // do-nothing } } //cout << local_size() << " of " << N << " probes found on processor " << MPI::process_number() << endl; }
void extract_dof_component_map(std::map<std::size_t, std::size_t>& dof_component_map, const FunctionSpace& VV, int* component) { // Extract sub dofmaps recursively and store dof to component map boost::unordered_map<std::size_t, std::size_t> collapsed_map; boost::unordered_map<std::size_t, std::size_t>::iterator map_it; std::vector<std::size_t> comp(1); if (VV.element()->num_sub_elements() == 0) { boost::shared_ptr<GenericDofMap> dummy = VV.dofmap()->collapse(collapsed_map, *VV.mesh()); (*component)++; for (map_it =collapsed_map.begin(); map_it!=collapsed_map.end(); ++map_it) dof_component_map[map_it->second] = (*component); } else { for (std::size_t i=0; i<VV.element()->num_sub_elements(); i++) { comp[0] = i; boost::shared_ptr<FunctionSpace> Vs = VV.extract_sub_space(comp); extract_dof_component_map(dof_component_map, *Vs, component); } } }
//----------------------------------------------------------------------------- Function::Function(const FunctionSpace& V) : Hierarchical<Function>(*this), _function_space(reference_to_no_delete_pointer(V)), _allow_extrapolation(dolfin::parameters["allow_extrapolation"]) { // Check that we don't have a subspace if (!V.component().empty()) { dolfin_error("Function.cpp", "create function", "Cannot be created from subspace. Consider collapsing the function space"); } // Initialize vector init_vector(); }
//----------------------------------------------------------------------------- void Extrapolation::add_cell_equations(Eigen::MatrixXd& A, Eigen::VectorXd& b, const Cell& cell0, const Cell& cell1, const std::vector<double>& coordinate_dofs0, const std::vector<double>& coordinate_dofs1, const ufc::cell& c0, const ufc::cell& c1, const FunctionSpace& V, const FunctionSpace& W, const Function& v, std::map<std::size_t, std::size_t>& dof2row) { // Extract coefficients for v on patch cell dolfin_assert(V.element()); std::vector<double> dof_values(V.element()->space_dimension()); v.restrict(&dof_values[0], *V.element(), cell1, coordinate_dofs1.data(), c1); // Create basis function dolfin_assert(W.element()); BasisFunction phi(0, W.element(), coordinate_dofs0); // Iterate over given local dofs for V on patch cell for (auto const &it : dof2row) { const std::size_t i = it.first; const std::size_t row = it.second; // Iterate over basis functions for W on center cell for (std::size_t j = 0; j < W.element()->space_dimension(); ++j) { // Create basis function phi.update_index(j); // Evaluate dof on basis function const double dof_value = V.element()->evaluate_dof(i, phi, coordinate_dofs1.data(), c1.orientation, c1); // Insert dof_value into matrix A(row, j) = dof_value; } // Insert coefficient into vector b[row] = dof_values[i]; } }
//----------------------------------------------------------------------------- void Extrapolation::add_cell_equations(arma::Mat<double>& A, arma::Col<double>& b, const Cell& cell0, const Cell& cell1, const ufc::cell& c0, const ufc::cell& c1, const FunctionSpace& V, const FunctionSpace& W, const Function& v, std::map<std::size_t, std::size_t>& dof2row) { // Extract coefficents for v on patch cell dolfin_assert(V.element()); std::vector<double> dof_values(V.element()->space_dimension()); v.restrict(&dof_values[0], *V.element(), cell1, c1); // Iterate over given local dofs for V on patch cell dolfin_assert(W.element()); for (std::map<std::size_t, std::size_t>::iterator it = dof2row.begin(); it!= dof2row.end(); it++) { const std::size_t i = it->first; const std::size_t row = it->second; // Iterate over basis functions for W on center cell for (std::size_t j = 0; j < W.element()->space_dimension(); ++j) { // Create basis function const BasisFunction phi(j, *W.element(), c0); // Evaluate dof on basis function const int cell_orientation = 0; const double dof_value = V.element()->evaluate_dof(i, phi, &c1.vertex_coordinates[0], cell_orientation, c1); // Insert dof_value into matrix A(row, j) = dof_value; } // Insert coefficient into vector b[row] = dof_values[i]; } }
FormulationPML:: FormulationPML(const GroupOfElement& domain, const FunctionSpace& fs, double k, void (*fS)(fullVector<double>& xyz, fullMatrix<Complex>& T), Complex (*fM)(fullVector<double>& xyz)){ // Check domain stats: uniform mesh // pair<bool, size_t> uniform = domain.isUniform(); size_t eType = uniform.second; if(!uniform.first) throw Exception("FormulationPML needs a uniform mesh"); // Save Data // ddomain = &domain; ffs = &fs; // Wavenumber squared // this->kSquare = k * k; // Get Basis // const Basis& basis = fs.getBasis(eType); const size_t order = basis.getOrder(); // Gaussian Quadrature // Quadrature gaussStif(eType, order - 1, 2); Quadrature gaussMass(eType, order, 2); const fullMatrix<double>& gCS = gaussStif.getPoints(); const fullMatrix<double>& gCM = gaussMass.getPoints(); // Functions // basis.preEvaluateDerivatives(gCS); basis.preEvaluateFunctions(gCM); // Local Terms // GroupOfJacobian jacS(domain, gCS, "invert"); GroupOfJacobian jacM(domain, gCM, "jacobian"); stif = new TermGradGrad<Complex> (jacS, basis, gaussStif, fS); mass = new TermFieldField<Complex>(jacM, basis, gaussMass, fM); }
//----------------------------------------------------------------------------- std::vector<dolfin::la_index> dolfin::vertex_to_dof_map(const FunctionSpace& space) { // Get the mesh dolfin_assert(space.mesh()); dolfin_assert(space.dofmap()); const Mesh& mesh = *space.mesh(); const GenericDofMap& dofmap = *space.dofmap(); if (dofmap.is_view()) { dolfin_error("fem_utils.cpp", "tabulate vertex to dof map", "Cannot tabulate vertex_to_dof_map for a subspace"); } // Initialize vertex to cell connections const std::size_t top_dim = mesh.topology().dim(); mesh.init(0, top_dim); // Num dofs per vertex const std::size_t dofs_per_vertex = dofmap.num_entity_dofs(0); const std::size_t vert_per_cell = mesh.topology()(top_dim, 0).size(0); if (vert_per_cell*dofs_per_vertex != dofmap.max_element_dofs()) { dolfin_error("DofMap.cpp", "tabulate dof to vertex map", "Can only tabulate dofs on vertices"); } // Allocate data for tabulating local to local map std::vector<std::size_t> local_to_local_map(dofs_per_vertex); // Create return data structure std::vector<dolfin::la_index> return_map(dofs_per_vertex*mesh.num_entities(0)); // Iterate over vertices std::size_t local_vertex_ind = 0; for (VertexIterator vertex(mesh, "all"); !vertex.end(); ++vertex) { // Get the first cell connected to the vertex const Cell cell(mesh, vertex->entities(top_dim)[0]); // Find local vertex number #ifdef DEBUG bool vertex_found = false; #endif for (std::size_t i = 0; i < cell.num_entities(0); i++) { if (cell.entities(0)[i] == vertex->index()) { local_vertex_ind = i; #ifdef DEBUG vertex_found = true; #endif break; } } dolfin_assert(vertex_found); // Get all cell dofs const ArrayView<const dolfin::la_index> cell_dofs = dofmap.cell_dofs(cell.index()); // Tabulate local to local map of dofs on local vertex dofmap.tabulate_entity_dofs(local_to_local_map, 0, local_vertex_ind); // Fill local dofs for the vertex for (std::size_t local_dof = 0; local_dof < dofs_per_vertex; local_dof++) { const dolfin::la_index global_dof = cell_dofs[local_to_local_map[local_dof]]; return_map[dofs_per_vertex*vertex->index() + local_dof] = global_dof; } } // Return the map return return_map; }
void ProlongationP(const FunctionSpace& V, const Array<int>& Mapping, const Array<double>& X, const Array<double>& Y, const Array<double>& Z, double * dataX, double * dataY, double * dataZ) { const Mesh mesh = *V.mesh(); const GenericDofMap& dofmap_u = *V.dofmap(); const int n = mesh.num_cells(); const int m = mesh.num_edges(); const int dim = mesh.geometry().dim(); // std::vector<double> coord = mesh.coordinates(); // /* // even are the x coords... // odd are the y coords... // */ // std::vector<double> X; // std::vector<double> Y; // std::vector<double> Z; // for (int i = 0; i < coord.size()/dim; ++i) // { // if (dim == 2) { // std::cout << 2*i << std::endl; // X.push_back(coord[2*i]); // Y.push_back(coord[2*i+1]); // } // else { // std::cout << 3*i << std::endl; // X.push_back(coord[3*i]); // Y.push_back(coord[3*i+1]); // Z.push_back(coord[3*i+2]); // } // } std::vector<double> tangent; std::vector<double> Ntangent; tangent.reserve(dim); Ntangent.reserve(dim); Edge* dolfin_edge; int k = -1; for (int i = 0; i < m; ++i) { k = k + 1; dolfin_edge = new Edge(mesh, i); const uint* edgeVERTICES = dolfin_edge->entities(0); tangent[0] = (X[edgeVERTICES[1]]-X[edgeVERTICES[0]]); tangent[1] = (Y[edgeVERTICES[1]]-Y[edgeVERTICES[0]]); if (dim == 3) { tangent[2] = Z[edgeVERTICES[1]]-Z[edgeVERTICES[0]]; } for (int j = 0; j < dim; ++j) { if (dim == 3) { if (tangent[0] == 0 && tangent[1] == 0 && tangent[2] == 0){ Ntangent[j] =0; } else { Ntangent[j] = tangent[j]/(sqrt(pow(tangent[0],2.0)+pow(tangent[1],2.0)+pow(tangent[2],2.0))); } } else { if (tangent[0] == 0 && tangent[1] == 0){ Ntangent[j] =0; } else { Ntangent[j] = tangent[j]/(sqrt(pow(tangent[0],2.0)+pow(tangent[1],2.0))); } } } double len = sqrt(pow(tangent[0],2.0)+pow(tangent[1],2.0)); // std::cout << len << " , " << dolfin_edge->length() << std::endl; dataX[k]=0.5*dolfin_edge->length()*Ntangent[0]; dataY[k]=0.5*dolfin_edge->length()*Ntangent[1]; if (dim == 3) { dataZ[k]=0.5*dolfin_edge->length()*Ntangent[2]; } k = k + 1; dataX[k]=0.5*dolfin_edge->length()*Ntangent[0]; dataY[k]=0.5*dolfin_edge->length()*Ntangent[1]; if (dim == 3) { dataZ[k]=0.5*dolfin_edge->length()*Ntangent[2]; } } }
void ProlongationGrad(const FunctionSpace& V, double * dataX, double * dataY, double * dataZ, double * data, double * row, double * column) { const Mesh mesh = *V.mesh(); const GenericDofMap& dofmap_u = *V.dofmap(); const int n = mesh.num_cells(); const int m = mesh.num_edges(); const int dim = mesh.geometry().dim(); std::vector<double> coord = mesh.coordinates(); /* even are the x coords... odd are the y coords... */ std::vector<double> X; std::vector<double> Y; std::vector<double> Z; for (int i = 0; i < coord.size()/dim; ++i) { if (dim == 2) { // std::cout << 2*i << std::endl; X.push_back(coord[2*i]); Y.push_back(coord[2*i+1]); } else { // std::cout << 3*i << std::endl; X.push_back(coord[3*i]); Y.push_back(coord[3*i+1]); Z.push_back(coord[3*i+2]); } } std::vector<double> tangent; std::vector<double> Ntangent; tangent.reserve(dim); Ntangent.reserve(dim); Edge* dolfin_edge; int k = -1; for (int i = 0; i < m; ++i) { k = k + 1; dolfin_edge = new Edge(mesh, i); const uint* edgeVERTICES = dolfin_edge->entities(0); tangent[0] = (X[edgeVERTICES[1]]-X[edgeVERTICES[0]]); tangent[1] = (Y[edgeVERTICES[1]]-Y[edgeVERTICES[0]]); if (dim == 3) { tangent[2] = Z[edgeVERTICES[1]]-Z[edgeVERTICES[0]]; } for (int j = 0; j < dim; ++j) { if (dim == 3) { if (tangent[0] == 0 && tangent[1] == 0 && tangent[2] == 0){ Ntangent[j] =0; } else { Ntangent[j] = tangent[j]/(sqrt(pow(tangent[0],2.0)+pow(tangent[1],2.0)+pow(tangent[2],2.0))); } } else { if (tangent[0] == 0 && tangent[1] == 0){ Ntangent[j] =0; } else { Ntangent[j] = tangent[j]/(sqrt(pow(tangent[0],2.0)+pow(tangent[1],2.0))); } } } // double len = sqrt(pow(tangent[0],2.0)+pow(tangent[1],2.0)); // std::cout << len << " , " << dolfin_edge->length() << std::endl; dataX[k]=0.5*dolfin_edge->length()*Ntangent[0]; dataY[k]=0.5*dolfin_edge->length()*Ntangent[1]; if (dim == 3) { dataZ[k]=0.5*dolfin_edge->length()*Ntangent[2]; } data[k] = -1; row[k] = i; column[k] = edgeVERTICES[0]; // std::cout << dataX[k] << std::endl; k = k + 1; dataX[k]=0.5*dolfin_edge->length()*Ntangent[0]; dataY[k]=0.5*dolfin_edge->length()*Ntangent[1]; if (dim == 3) { dataZ[k]=0.5*dolfin_edge->length()*Ntangent[2]; } data[k] = 1; row[k] = i; column[k] = edgeVERTICES[1]; // std::cout << dataX[k] << std::endl; } }
//----------------------------------------------------------------------------- void XMLFunctionData::build_dof_map(std::vector<std::vector<uint> >& dof_map, const FunctionSpace& V) { // Get mesh and dofmap dolfin_assert(V.mesh()); dolfin_assert(V.dofmap()); const Mesh& mesh = *V.mesh(); const GenericDofMap& dofmap = *V.dofmap(); const uint num_cells = MPI::sum(mesh.num_cells()); std::vector<std::vector<std::vector<uint > > > gathered_dofmap; std::vector<std::vector<uint > > local_dofmap(mesh.num_cells()); if (MPI::num_processes() > 1) { // Get local-to-global cell numbering dolfin_assert(mesh.parallel_data().have_global_entity_indices(mesh.topology().dim())); const MeshFunction<uint>& global_cell_indices = mesh.parallel_data().global_entity_indices(mesh.topology().dim()); // Build dof map data with global cell indices for (CellIterator cell(mesh); !cell.end(); ++cell) { const uint local_cell_index = cell->index(); const uint global_cell_index = global_cell_indices[*cell]; local_dofmap[local_cell_index] = dofmap.cell_dofs(local_cell_index); local_dofmap[local_cell_index].push_back(global_cell_index); } } else { // Build dof map data for (CellIterator cell(mesh); !cell.end(); ++cell) { const uint local_cell_index = cell->index(); local_dofmap[local_cell_index] = dofmap.cell_dofs(local_cell_index); local_dofmap[local_cell_index].push_back(local_cell_index); } } // Gather dof map data on root process MPI::gather(local_dofmap, gathered_dofmap); // Build global dofmap on root process if (MPI::process_number() == 0) { dof_map.resize(num_cells); // Loop of dof map from each process std::vector<std::vector<std::vector<uint > > > ::const_iterator proc_dofmap; for (proc_dofmap = gathered_dofmap.begin(); proc_dofmap != gathered_dofmap.end(); ++proc_dofmap) { std::vector<std::vector<uint> >::const_iterator cell_dofmap; for (cell_dofmap = proc_dofmap->begin(); cell_dofmap != proc_dofmap->end(); ++cell_dofmap) { const std::vector<uint>& cell_dofs = *cell_dofmap; const uint global_cell_index = cell_dofs.back(); dolfin_assert(global_cell_index < dof_map.size()); dof_map[global_cell_index] = *cell_dofmap; dof_map[global_cell_index].pop_back(); } } } }
//----------------------------------------------------------------------------- void XMLFunctionData::build_dof_map(std::vector<std::vector<la_index>>& dof_map, const FunctionSpace& V) { // Get mesh and dofmap dolfin_assert(V.mesh()); dolfin_assert(V.dofmap()); const Mesh& mesh = *V.mesh(); const GenericDofMap& dofmap = *V.dofmap(); // Get local-to-global map std::vector<std::size_t> local_to_global_dof; dofmap.tabulate_local_to_global_dofs(local_to_global_dof); // Get global number of cells const std::size_t num_cells = MPI::sum(mesh.mpi_comm(), mesh.num_cells()); std::vector<dolfin::la_index> local_dofmap; if (MPI::size(mesh.mpi_comm()) > 1) { // Check that local-to-global cell numbering is available const std::size_t D = mesh.topology().dim(); dolfin_assert(mesh.topology().have_global_indices(D)); // Build dof map data with global cell indices std::vector<la_index> cell_dofs_global; for (CellIterator cell(mesh); !cell.end(); ++cell) { const std::size_t local_cell_index = cell->index(); const std::size_t global_cell_index = cell->global_index(); auto cell_dofs = dofmap.cell_dofs(local_cell_index); local_dofmap.push_back(global_cell_index); local_dofmap.push_back(cell_dofs.size()); cell_dofs_global.resize(cell_dofs.size()); for(Eigen::Index i = 0; i < cell_dofs.size(); ++i) cell_dofs_global[i] = local_to_global_dof[cell_dofs[i]]; // Insert global dof indices local_dofmap.insert(local_dofmap.end(), cell_dofs_global.data(), cell_dofs_global.data() + cell_dofs_global.size()); } } else { // Build dof map data for (CellIterator cell(mesh); !cell.end(); ++cell) { const std::size_t local_cell_index = cell->index(); local_dofmap.push_back(local_cell_index); local_dofmap.push_back(dofmap.cell_dofs(local_cell_index).size()); auto dmap = dofmap.cell_dofs(local_cell_index); local_dofmap.insert(local_dofmap.end(), dmap.data(), dmap.data() + dmap.size()); } } // Gather dof map data on root process std::vector<dolfin::la_index> gathered_dofmap; MPI::gather(mesh.mpi_comm(), local_dofmap, gathered_dofmap); // Build global dofmap on root process if (MPI::rank(mesh.mpi_comm()) == 0) { dof_map.resize(num_cells); for (std::size_t i = 0; i < gathered_dofmap.size(); ) { const std::size_t global_cell_index = gathered_dofmap[i++]; const std::size_t num_dofs = gathered_dofmap[i++]; for (std::size_t j = 0; j < num_dofs; ++j) dof_map[global_cell_index].push_back(gathered_dofmap[i++]); } } }
void compute(const Options& option){ // Get Type // int type; if(option.getValue("-type")[1].compare("scalar") == 0){ cout << "Scalar Waveguide" << endl << flush; type = scal; } else if(option.getValue("-type")[1].compare("vector") == 0){ cout << "Vetorial Waveguide" << endl << flush; type = vect; } else throw Exception("Bad -type: %s", option.getValue("-type")[1].c_str()); // Get Parameters // const size_t nDom = atoi(option.getValue("-n")[1].c_str()); k = atof(option.getValue("-k")[1].c_str()); const size_t order = atoi(option.getValue("-o")[1].c_str()); const double sigma = atof(option.getValue("-sigma")[1].c_str()); cout << "Wavenumber: " << k << endl << "Order: " << order << endl << "# Domain: " << nDom << endl << flush; // Get Domains // Mesh msh(option.getValue("-msh")[1]); GroupOfElement source(msh.getFromPhysical(1 * nDom + 1)); GroupOfElement zero(msh.getFromPhysical(2 * nDom + 2)); GroupOfElement infinity(msh.getFromPhysical(2 * nDom + 1)); GroupOfElement volume(msh); vector<GroupOfElement*> perVolume(nDom); for(size_t i = 0; i < nDom; i++){ perVolume[i] = new GroupOfElement(msh.getFromPhysical(i + 1)); volume.add(*perVolume[i]); } // Full Domain // vector<const GroupOfElement*> domain(4); domain[0] = &volume; domain[1] = &source; domain[2] = &zero; domain[3] = &infinity; // Function Space // FunctionSpace* fs = NULL; if(type == scal) fs = new FunctionSpaceScalar(domain, order); else fs = new FunctionSpaceVector(domain, order); // Steady Wave Formulation // const double Z0 = 119.9169832 * M_PI; const Complex epsr(1, 1 / k * Z0 * sigma); const Complex mur(1, 0); FormulationSteadyWave<Complex> wave(volume, *fs, k); FormulationImpedance impedance(infinity, *fs, k, epsr, mur); // Solve // System<Complex> system; system.addFormulation(wave); system.addFormulation(impedance); // Constraint if(fs->isScalar()){ SystemHelper<Complex>::dirichlet(system, *fs, zero , fZeroScal); SystemHelper<Complex>::dirichlet(system, *fs, source, fSourceScal); } else{ SystemHelper<Complex>::dirichlet(system, *fs, zero , fZeroVect); SystemHelper<Complex>::dirichlet(system, *fs, source, fSourceVect); } // Assemble system.assemble(); cout << "Assembled: " << system.getSize() << endl << flush; // Sove system.solve(); cout << "Solved!" << endl << flush; // Draw Solution // try{ option.getValue("-nopos"); } catch(...){ cout << "Writing solution..." << endl << flush; stringstream stream; try{ vector<string> name = option.getValue("-name"); stream << name[1]; } catch(...){ stream << "waveguide"; } try{ // Get Visu Mesh // vector<string> visuStr = option.getValue("-interp"); Mesh visuMsh(visuStr[1]); // Get Solution // map<Dof, Complex> sol; FormulationHelper::initDofMap(*fs, volume, sol); system.getSolution(sol, 0); // Interoplate // for(size_t i = 0; i < nDom; i++){ // GroupOfElement to interoplate on GroupOfElement visuGoe(visuMsh.getFromPhysical(i + 1)); // Interpolation stringstream name; name << stream.str() << i << ".dat"; map<const MVertex*, vector<Complex> > map; Interpolator<Complex>::interpolate(*perVolume[i], visuGoe, *fs,sol,map); Interpolator<Complex>::write(name.str(), map); } } catch(...){ FEMSolution<Complex> feSol; system.getSolution(feSol, *fs, volume); feSol.write(stream.str()); } } // Clean // for(size_t i = 0; i < nDom; i++) delete perVolume[i]; delete fs; }
//----------------------------------------------------------------------------- void Extrapolation::compute_coefficients( std::vector<std::vector<double>>& coefficients, const Function& v, const FunctionSpace& V, const FunctionSpace& W, const Cell& cell0, const std::vector<double>& coordinate_dofs0, const ufc::cell& c0, const ArrayView<const dolfin::la_index>& dofs, std::size_t& offset) { // Call recursively for mixed elements dolfin_assert(V.element()); const std::size_t num_sub_spaces = V.element()->num_sub_elements(); if (num_sub_spaces > 0) { for (std::size_t k = 0; k < num_sub_spaces; k++) { compute_coefficients(coefficients, v[k], *V[k], *W[k], cell0, coordinate_dofs0, c0, dofs, offset); } return; } // Build data structures for keeping track of unique dofs std::map<std::size_t, std::map<std::size_t, std::size_t>> cell2dof2row; std::set<std::size_t> unique_dofs; build_unique_dofs(unique_dofs, cell2dof2row, cell0, V); // Compute size of linear system dolfin_assert(W.element()); const std::size_t N = W.element()->space_dimension(); const std::size_t M = unique_dofs.size(); // Check size of system if (M < N) { dolfin_error("Extrapolation.cpp", "compute extrapolation", "Not enough degrees of freedom on local patch to build extrapolation"); } // Create matrix and vector for linear system Eigen::MatrixXd A(M, N); Eigen::VectorXd b(M); // Add equations on cell and neighboring cells dolfin_assert(V.mesh()); ufc::cell c1; std::vector<double> coordinate_dofs1; // Get unique set of surrounding cells (including cell0) std::set<std::size_t> cell_set; for (VertexIterator vtx(cell0); !vtx.end(); ++vtx) { for (CellIterator cell1(*vtx); !cell1.end(); ++cell1) cell_set.insert(cell1->index()); } for (auto cell_it : cell_set) { if (cell2dof2row[cell_it].empty()) continue; Cell cell1(cell0.mesh(), cell_it); cell1.get_coordinate_dofs(coordinate_dofs1); cell1.get_cell_data(c1); add_cell_equations(A, b, cell0, cell1, coordinate_dofs0, coordinate_dofs1, c0, c1, V, W, v, cell2dof2row[cell_it]); } // Solve least squares system const Eigen::VectorXd x = A.jacobiSvd(Eigen::ComputeThinU | Eigen::ComputeThinV).solve(b); // Insert resulting coefficients into global coefficient vector dolfin_assert(W.dofmap()); for (std::size_t i = 0; i < W.dofmap()->num_element_dofs(cell0.index()); ++i) coefficients[dofs[i + offset]].push_back(x[i]); // Increase offset offset += W.dofmap()->num_element_dofs(cell0.index()); }