action functions
|
Please note that the library has not been "officially" released. While we continue to work on the documentation, these web pages are likely to contain broken links and documents in draft form. Please send an email to if you wish to be informed of the library's "official" release. |
00001 //LIC// ==================================================================== 00002 //LIC// This file forms part of oomph-lib, the object-oriented, 00003 //LIC// multi-physics finite-element library, available 00004 //LIC// at http://www.oomph-lib.org. 00005 //LIC// 00006 //LIC// Version 0.90. August 3, 2009. 00007 //LIC// 00008 //LIC// Copyright (C) 2006-2009 Matthias Heil and Andrew Hazel 00009 //LIC// 00010 //LIC// This library is free software; you can redistribute it and/or 00011 //LIC// modify it under the terms of the GNU Lesser General Public 00012 //LIC// License as published by the Free Software Foundation; either 00013 //LIC// version 2.1 of the License, or (at your option) any later version. 00014 //LIC// 00015 //LIC// This library is distributed in the hope that it will be useful, 00016 //LIC// but WITHOUT ANY WARRANTY; without even the implied warranty of 00017 //LIC// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 00018 //LIC// Lesser General Public License for more details. 00019 //LIC// 00020 //LIC// You should have received a copy of the GNU Lesser General Public 00021 //LIC// License along with this library; if not, write to the Free Software 00022 //LIC// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 00023 //LIC// 02110-1301 USA. 00024 //LIC// 00025 //LIC// The authors may be contacted at oomph-lib@maths.man.ac.uk. 00026 //LIC// 00027 //LIC//==================================================================== 00028 // Driver for solution of 2D Poisson equation in fish-shaped domain with 00029 // adaptivity 00030 00031 00032 // Generic oomph-lib headers 00033 #include "generic.h" 00034 00035 // The Poisson equations 00036 #include "poisson.h" 00037 00038 // The fish mesh 00039 #include "meshes/fish_mesh.h" 00040 00041 using namespace std; 00042 00043 using namespace oomph; 00044 00045 00046 //============ start_of_namespace===================================== 00047 /// Namespace for const source term in Poisson equation 00048 //==================================================================== 00049 namespace ConstSourceForPoisson 00050 { 00051 00052 /// Strength of source function: default value -1.0 00053 double Strength=-1.0; 00054 00055 /// Const source function 00056 void source_function(const Vector<double>& x, double& source) 00057 { 00058 source = Strength; 00059 } 00060 00061 } // end of namespace 00062 00063 00064 00065 00066 //======start_of_problem_class======================================== 00067 /// Refineable Poisson problem in fish-shaped domain. 00068 /// Template parameter identifies the element type. 00069 //==================================================================== 00070 template<class ELEMENT> 00071 class RefineableFishPoissonProblem : public Problem 00072 { 00073 00074 public: 00075 00076 /// Constructor 00077 RefineableFishPoissonProblem(); 00078 00079 /// Destructor: Empty 00080 virtual ~RefineableFishPoissonProblem(){} 00081 00082 /// Update the problem specs after solve (empty) 00083 void actions_after_newton_solve() {} 00084 00085 /// Update the problem specs before solve (empty) 00086 void actions_before_newton_solve() {} 00087 00088 /// \short Overloaded version of the problem's access function to 00089 /// the mesh. Recasts the pointer to the base Mesh object to 00090 /// the actual mesh type. 00091 RefineableFishMesh<ELEMENT>* mesh_pt() 00092 { 00093 return dynamic_cast<RefineableFishMesh<ELEMENT>*>(Problem::mesh_pt()); 00094 } 00095 00096 /// \short Doc the solution. Output directory and labels are specified 00097 /// by DocInfo object 00098 void doc_solution(DocInfo& doc_info); 00099 00100 }; // end of problem class 00101 00102 00103 00104 00105 00106 //===========start_of_constructor========================================= 00107 /// Constructor for adaptive Poisson problem in fish-shaped 00108 /// domain. 00109 //======================================================================== 00110 template<class ELEMENT> 00111 RefineableFishPoissonProblem<ELEMENT>::RefineableFishPoissonProblem() 00112 { 00113 00114 // Build fish mesh -- this is a coarse base mesh consisting 00115 // of four elements. We'll refine/adapt the mesh later. 00116 Problem::mesh_pt()=new RefineableFishMesh<ELEMENT>; 00117 00118 // Create/set error estimator 00119 mesh_pt()->spatial_error_estimator_pt()=new Z2ErrorEstimator; 00120 00121 // Set the boundary conditions for this problem: All nodes are 00122 // free by default -- just pin the ones that have Dirichlet conditions 00123 // here. Since the boundary values are never changed, we set 00124 // them here rather than in actions_before_newton_solve(). 00125 unsigned n_bound = mesh_pt()->nboundary(); 00126 for(unsigned i=0;i<n_bound;i++) 00127 { 00128 unsigned n_node = mesh_pt()->nboundary_node(i); 00129 for (unsigned n=0;n<n_node;n++) 00130 { 00131 // Pin the single scalar value at this node 00132 mesh_pt()->boundary_node_pt(i,n)->pin(0); 00133 00134 // Assign the homogenous boundary condition for the one and only 00135 // nodal value 00136 mesh_pt()->boundary_node_pt(i,n)->set_value(0,0.0); 00137 } 00138 } 00139 00140 // Loop over elements and set pointers to source function 00141 unsigned n_element = mesh_pt()->nelement(); 00142 for(unsigned e=0;e<n_element;e++) 00143 { 00144 // Upcast from FiniteElement to the present element 00145 ELEMENT *el_pt = dynamic_cast<ELEMENT*>(mesh_pt()->element_pt(e)); 00146 00147 //Set the source function pointer 00148 el_pt->source_fct_pt() = &ConstSourceForPoisson::source_function; 00149 } 00150 00151 // Setup the equation numbering scheme 00152 cout <<"Number of equations: " << assign_eqn_numbers() << std::endl; 00153 00154 } // end of constructor 00155 00156 00157 00158 00159 //=======start_of_doc===================================================== 00160 /// Doc the solution in tecplot format. 00161 //======================================================================== 00162 template<class ELEMENT> 00163 void RefineableFishPoissonProblem<ELEMENT>::doc_solution(DocInfo& doc_info) 00164 { 00165 00166 ofstream some_file; 00167 char filename[100]; 00168 00169 // Number of plot points in each coordinate direction. 00170 unsigned npts; 00171 npts=5; 00172 00173 // Output solution 00174 sprintf(filename,"%s/soln%i.dat",doc_info.directory().c_str(), 00175 doc_info.number()); 00176 some_file.open(filename); 00177 mesh_pt()->output(some_file,npts); 00178 some_file.close(); 00179 00180 } // end of doc 00181 00182 00183 00184 00185 00186 00187 //=====================start_of_incremental=============================== 00188 /// Demonstrate how to solve 2D Poisson problem in 00189 /// fish-shaped domain with mesh adaptation. First we solve on the original 00190 /// coarse mesh. Next we do a few uniform refinement steps and re-solve. 00191 /// Finally, we enter into an automatic adapation loop. 00192 //======================================================================== 00193 void solve_with_incremental_adaptation() 00194 { 00195 00196 //Set up the problem with nine-node refineable Poisson elements 00197 RefineableFishPoissonProblem<RefineableQPoissonElement<2,3> > problem; 00198 00199 // Setup labels for output 00200 //------------------------ 00201 DocInfo doc_info; 00202 00203 // Set output directory 00204 doc_info.set_directory("RESLT_incremental"); 00205 00206 // Step number 00207 doc_info.number()=0; 00208 00209 00210 // Doc (default) refinement targets 00211 //---------------------------------- 00212 problem.mesh_pt()->doc_adaptivity_targets(cout); 00213 00214 // Solve/doc the problem on the initial, very coarse mesh 00215 //------------------------------------------------------- 00216 00217 // Solve the problem 00218 problem.newton_solve(); 00219 00220 //Output solution 00221 problem.doc_solution(doc_info); 00222 00223 //Increment counter for solutions 00224 doc_info.number()++; 00225 00226 00227 // Do three rounds of uniform mesh refinement and re-solve 00228 //-------------------------------------------------------- 00229 problem.refine_uniformly(); 00230 problem.refine_uniformly(); 00231 problem.refine_uniformly(); 00232 00233 // Solve the problem 00234 problem.newton_solve(); 00235 00236 //Output solution 00237 problem.doc_solution(doc_info); 00238 00239 //Increment counter for solutions 00240 doc_info.number()++; 00241 00242 00243 // Now do (up to) four rounds of fully automatic adapation in response to 00244 //----------------------------------------------------------------------- 00245 // error estimate 00246 //--------------- 00247 unsigned max_solve=4; 00248 for (unsigned isolve=0;isolve<max_solve;isolve++) 00249 { 00250 // Adapt problem/mesh 00251 problem.adapt(); 00252 00253 // Re-solve the problem if the adaptation has changed anything 00254 if ((problem.mesh_pt()->nrefined() !=0)|| 00255 (problem.mesh_pt()->nunrefined()!=0)) 00256 { 00257 problem.newton_solve(); 00258 } 00259 else 00260 { 00261 cout << "Mesh wasn't adapted --> we'll stop here" << std::endl; 00262 break; 00263 } 00264 00265 //Output solution 00266 problem.doc_solution(doc_info); 00267 00268 //Increment counter for solutions 00269 doc_info.number()++; 00270 } 00271 00272 00273 } // end of incremental 00274 00275 00276 00277 00278 00279 00280 //================================start_black_box========================= 00281 /// Demonstrate how to solve 2D Poisson problem in 00282 /// fish-shaped domain with fully automatic mesh adaptation 00283 //======================================================================== 00284 void solve_with_fully_automatic_adaptation() 00285 { 00286 00287 //Set up the problem with nine-node refineable Poisson elements 00288 RefineableFishPoissonProblem<RefineableQPoissonElement<2,3> > problem; 00289 00290 // Setup labels for output 00291 //------------------------ 00292 DocInfo doc_info; 00293 00294 // Set output directory 00295 doc_info.set_directory("RESLT_fully_automatic"); 00296 00297 // Step number 00298 doc_info.number()=0; 00299 00300 00301 // Doc (default) refinement targets 00302 //---------------------------------- 00303 problem.mesh_pt()->doc_adaptivity_targets(cout); 00304 00305 00306 // Solve/doc the problem with fully automatic adaptation 00307 //------------------------------------------------------ 00308 00309 // Maximum number of adaptations: 00310 unsigned max_adapt=5; 00311 00312 // Solve the problem; perform up to specified number of adaptations. 00313 problem.newton_solve(max_adapt); 00314 00315 //Output solution 00316 problem.doc_solution(doc_info); 00317 00318 } // end black box 00319 00320 00321 00322 00323 //=================start_of_main========================================== 00324 /// Demonstrate how to solve 2D Poisson problem in 00325 /// fish-shaped domain with mesh adaptation. 00326 //======================================================================== 00327 int main() 00328 { 00329 // Solve with adaptation, docing the intermediate steps 00330 solve_with_incremental_adaptation(); 00331 00332 // Solve directly, with fully automatic adaptation 00333 solve_with_fully_automatic_adaptation(); 00334 00335 } // end of main 00336 00337 00338 00339 00340 // //Do few unrefinements and keep doc-ing 00341 // for (unsigned i=0;i<5;i++) 00342 // { 00343 // problem.unrefine_uniformly(); 00344 00345 // //Output solution 00346 // problem.doc_solution(doc_info); 00347 00348 // //Increment counter for solutions 00349 // doc_info.number()++; 00350 // }
1.4.7