• Main Page
  • Related Pages
  • Namespaces
  • Classes
  • Files
  • File List
  • File Members

AAdapt_STKUnifSizeField.cpp

Go to the documentation of this file.
00001 //*****************************************************************//
00002 //    Albany 2.0:  Copyright 2012 Sandia Corporation               //
00003 //    This Software is released under the BSD license detailed     //
00004 //    in the file "license.txt" in the top-level Albany directory  //
00005 //*****************************************************************//
00006 
00007 #include "AAdapt_STKUnifSizeField.hpp"
00008 #include "Albany_AbstractSTKFieldContainer.hpp"
00009 #include "Epetra_Import.h"
00010 
00011 /*
00012  * Utility functions (from stk_adapt/regression_tests/RegressionTestLocalRefiner.cpp)
00013  */
00014 
00015 static void normalize(double input_normal[3], double normal[3]) {
00016   double sum = std::sqrt(input_normal[0] * input_normal[0] +
00017                          input_normal[1] * input_normal[1] +
00018                          input_normal[2] * input_normal[2]);
00019   normal[0] = input_normal[0] / sum;
00020   normal[1] = input_normal[1] / sum;
00021   normal[2] = input_normal[2] / sum;
00022 }
00023 
00024 static void normalize(double input_output_normal[3]) {
00025   normalize(input_output_normal, input_output_normal);
00026 }
00027 
00028 static double distance(double c0[3], double c1[3]) {
00029   return std::sqrt((c0[0] - c1[0]) * (c0[0] - c1[0]) + (c0[1] - c1[1]) * (c0[1] - c1[1]) + (c0[2] - c1[2]) * (c0[2] - c1[2]));
00030 }
00031 
00032 static void difference(double v01[3], double c0[3], double c1[3]) {
00033   v01[0] = c0[0] - c1[0];
00034   v01[1] = c0[1] - c1[1];
00035   v01[2] = c0[2] - c1[2];
00036 }
00037 
00038 static double dot(double c0[3], double c1[3]) {
00039   return c0[0] * c1[0] + c0[1] * c1[1] + c0[2] * c1[2];
00040 }
00041 
00042 static double plane_dot_product(double plane_point[3], double plane_normal[3], double point[3]) {
00043   double normal[3] = {0, 0, 0};
00044   normalize(plane_normal, normal);
00045   double dot = 0.0;
00046 
00047   for(int i = 0; i < 3; i++) {
00048     dot += (point[i] - plane_point[i]) * normal[i];
00049   }
00050 
00051   return dot;
00052 }
00053 
00054 #if 0
00055 static void project_point_to_plane(double plane_point[3], double plane_normal[3], double point[3], double projected_point[3]) {
00056   double normal[3] = {0, 0, 0};
00057   normalize(plane_normal, normal);
00058   double dot = plane_dot_product(plane_point, plane_normal, point);
00059 
00060   for(int i = 0; i < 3; i++) {
00061     projected_point[i] = plane_point[i] + (point[i] - dot * normal[i]);
00062   }
00063 }
00064 #endif
00065 
00066 
00067 bool
00068 AAdapt::STKUnifRefineField::operator()(const stk::mesh::Entity& element,
00069                                        stk::mesh::FieldBase* field,  const stk::mesh::BulkData& bulkData) {
00070 
00071   /*
00072     double plane_point[3] = {2, 0, 0};
00073     double plane_normal[3] = {1, .5, -.5};
00074   */
00075   double plane_point[3] = {0, 0.7, 0};
00076   double plane_normal[3] = {0, 1, 0};
00077 
00078   const stk::mesh::PairIterRelation elem_nodes = element.relations(stk::mesh::fem::FEMMetaData::NODE_RANK);
00079   unsigned num_node = elem_nodes.size();
00080   double* f_data = stk::percept::PerceptMesh::field_data_entity(field, element);
00081   Albany::AbstractSTKFieldContainer::VectorFieldType* coordField = m_eMesh.get_coordinates_field();
00082 
00083   bool found = false;
00084 
00085   for(unsigned inode = 0; inode < num_node - 1; inode++) {
00086     stk::mesh::Entity& node_i = * elem_nodes[ inode ].entity();
00087     double* coord_data_i = stk::percept::PerceptMesh::field_data(coordField, node_i);
00088 
00089     for(unsigned jnode = inode + 1; jnode < num_node; jnode++) {
00090       stk::mesh::Entity& node_j = * elem_nodes[ jnode ].entity();
00091       double* coord_data_j = stk::percept::PerceptMesh::field_data(coordField, node_j);
00092 
00093       double dot_0 = plane_dot_product(plane_point, plane_normal, coord_data_i);
00094       double dot_1 = plane_dot_product(plane_point, plane_normal, coord_data_j);
00095 
00096       // if edge crosses the plane...
00097       if(dot_0 * dot_1 < 0) {
00098         found = true;
00099         break;
00100       }
00101     }
00102   }
00103 
00104   if(found) {
00105     f_data[0] = 1.0;
00106     //    std::cout << "Splitting: " << element.identifier() << std::endl;
00107   }
00108 
00109   else {
00110     f_data[0] = 0.0;
00111     //    std::cout << "Not splitting: " << element.identifier() << std::endl;
00112   }
00113 
00114   return false;  // don't terminate the loop
00115 }
00116 
00117 bool
00118 AAdapt::STKUnifUnrefineField::operator()(const stk::mesh::Entity& element,
00119     stk::mesh::FieldBase* field,  const stk::mesh::BulkData& bulkData) {
00120 
00121   const stk::mesh::PairIterRelation elem_nodes = element.relations(stk::mesh::fem::FEMMetaData::NODE_RANK);
00122   unsigned num_node = elem_nodes.size();
00123   double* f_data = stk::percept::PerceptMesh::field_data_entity(field, element);
00124   Albany::AbstractSTKFieldContainer::VectorFieldType* coordField = m_eMesh.get_coordinates_field();
00125 
00126   bool found = true;
00127 
00128   for(unsigned inode = 0; inode < num_node; inode++) {
00129     stk::mesh::Entity& node = * elem_nodes[ inode ].entity();
00130     double* coord_data = stk::percept::PerceptMesh::field_data(coordField, node);
00131 
00132     if(coord_data[0] < 0.0 || coord_data[1] < 0.0) { // || coord_data[2] > 1.1)
00133       found = false;
00134       break;
00135     }
00136   }
00137 
00138   if(found)
00139     f_data[0] = -1.0;
00140 
00141   else
00142     f_data[0] = 0.0;
00143 
00144   return false;  // don't terminate the loop
00145 }
00146 
00147 
00148 
00149 

Generated on Wed Mar 26 2014 18:36:35 for Albany: a Trilinos-based PDE code by  doxygen 1.7.1