void SmartLaplacianSmoother::optimize_vertex_positions( PatchData &pd, MsqError &err ) { assert(pd.num_free_vertices() == 1); const size_t center_vtx_index = 0; const size_t init_inverted = num_inverted( pd, err ); MSQ_ERRRTN(err); adjVtxList.clear(); pd.get_adjacent_vertex_indices( center_vtx_index, adjVtxList, err ); MSQ_ERRRTN(err); if (adjVtxList.empty()) return; const MsqVertex* verts = pd.get_vertex_array(err); const size_t n = adjVtxList.size(); const Vector3D orig_pos = verts[center_vtx_index]; Vector3D new_pos = verts[ adjVtxList[0] ]; for (size_t i = 1; i < n; ++i) new_pos += verts[ adjVtxList[i] ]; new_pos *= 1.0/n; pd.set_vertex_coordinates( new_pos, center_vtx_index, err ); pd.snap_vertex_to_domain( center_vtx_index, err ); MSQ_ERRRTN(err); const size_t new_inverted = num_inverted( pd, err ); MSQ_ERRRTN(err); if (new_inverted > init_inverted) pd.set_vertex_coordinates( orig_pos, center_vtx_index, err ); }
void BoundedCylinderDomain::create_curve( double distance, Mesh* mesh, double tolerance, MsqError& err ) { std::vector<Mesh::VertexHandle> handles; mesh->get_all_vertices( handles, err ); MSQ_ERRRTN(err); if (handles.empty()) { MSQ_SETERR(err)("No vertices in mesh.\n", MsqError::INVALID_ARG ); return; } std::vector<MsqVertex> coords(handles.size()); mesh->vertices_get_coordinates( arrptr(handles), arrptr(coords), handles.size(), err ); MSQ_ERRRTN(err); std::vector<Mesh::EntityHandle> list; Vector3D close, normal; for (size_t i = 0; i < handles.size(); ++i) { evaluate( distance, coords[i], close, normal ); if ((coords[i] - close).length() < tolerance) list.push_back( handles[i] ); } if (list.empty()) { MSQ_SETERR(err)("No vertices within specified tolerance.\n", MsqError::INVALID_ARG ); return; } create_curve( distance, list ); }
void TerminationCriterion::accumulate_inner( PatchData& pd, OFEvaluator& of_eval, MsqError& err ) { double of_value = 0; if (terminationCriterionFlag & GRAD_FLAGS) { mGrad.resize( pd.num_free_vertices() ); bool b = of_eval.evaluate(pd, of_value, mGrad, err); MSQ_ERRRTN(err); if (!b) { MSQ_SETERR(err)("Initial patch is invalid for gradient compuation.", MsqError::INVALID_MESH); return; } } else if (terminationCriterionFlag & OF_FLAGS) { bool b = of_eval.evaluate(pd, of_value, err); MSQ_ERRRTN(err); if (!b) { MSQ_SETERR(err)("Invalid patch passed to TerminationCriterion.", MsqError::INVALID_MESH); return; } } accumulate_inner( pd, of_value, mGrad.empty() ? 0 : arrptr(mGrad), err ); MSQ_CHKERR(err); }
void TagVertexMesh::copy_all_coordinates( MsqError& err ) { if (!haveTagHandle) { tagHandle = get_mesh()->tag_create( tagName, Mesh::DOUBLE, 3, 0, err ); MSQ_ERRRTN(err); haveTagHandle = true; } std::vector<Mesh::VertexHandle> handles; get_all_vertices( handles, err ); MSQ_ERRRTN(err); if (handles.empty()) return; std::vector<MsqVertex> coords(handles.size()); get_mesh()->vertices_get_coordinates( arrptr(handles), arrptr(coords), handles.size(), err ); MSQ_ERRRTN(err); std::vector<double> data( 3*handles.size() ); std::vector<double>::iterator j = data.begin(); std::vector<MsqVertex>::const_iterator i = coords.begin(); while (i != coords.end()) { i->get_coordinates( &*j ); ++i; j += 3; } tag_set_vertex_data( tagHandle, handles.size(), arrptr(handles), arrptr(data), err ); MSQ_ERRRTN(err); }
void MappingFunction3D::jacobian( const PatchData& pd, size_t element_number, NodeSet nodeset, Sample location, size_t* vertex_patch_indices_out, MsqVector<3>* d_coeff_d_xi_out, size_t& num_vtx_out, MsqMatrix<3,3>& jacobian_out, MsqError& err ) const { const MsqMeshEntity& elem = pd.element_by_index( element_number ); const size_t* conn = elem.get_vertex_index_array(); derivatives( location, nodeset, vertex_patch_indices_out, d_coeff_d_xi_out, num_vtx_out, err ); MSQ_ERRRTN(err); convert_connectivity_indices( elem.node_count(), vertex_patch_indices_out, num_vtx_out, err ); MSQ_ERRRTN(err); jacobian_out.zero(); size_t w = 0; for (size_t r = 0; r < num_vtx_out; ++r) { size_t i = conn[vertex_patch_indices_out[r]]; MsqMatrix<3,1> coords( pd.vertex_by_index( i ).to_array() ); jacobian_out += coords * transpose(d_coeff_d_xi_out[r]); if (i < pd.num_free_vertices()) { vertex_patch_indices_out[w] = i; d_coeff_d_xi_out[w] = d_coeff_d_xi_out[r]; ++w; } } num_vtx_out = w; }
void CompositeOFAdd::initialize_queue( MeshDomainAssoc* mesh_and_domain, const Settings* settings, MsqError& err ) { objFunc1->initialize_queue( mesh_and_domain, settings, err ); MSQ_ERRRTN(err); objFunc2->initialize_queue( mesh_and_domain, settings, err ); MSQ_ERRRTN(err); }
void EdgeIterator::get_adjacent_vertices( MsqError& err ) { adjList.clear(); // Get all adjacent elements size_t num_elem; const size_t* elems = patchPtr->get_vertex_element_adjacencies( vertIdx, num_elem, err ); MSQ_ERRRTN(err); // Get all adjacent vertices from elements std::vector<size_t> elem_verts; for (size_t e = 0; e < num_elem; ++e) { MsqMeshEntity& elem = patchPtr->element_by_index(elems[e]); EntityTopology type = elem.get_element_type(); size_t num_edges = TopologyInfo::edges( type ); bool mid_edge, mid_face, mid_vol; TopologyInfo::higher_order( type, elem.node_count(), mid_edge, mid_face, mid_vol, err ); MSQ_ERRRTN(err); // For each edge for (size_t d = 0; d < num_edges; ++d) { const unsigned* edge = TopologyInfo::edge_vertices( type, d, err ); MSQ_ERRRTN(err); size_t vert1 = elem.get_vertex_index( edge[0] ); size_t vert2 = elem.get_vertex_index( edge[1] ); size_t mid = ~(size_t)0; if (mid_edge) { int p = TopologyInfo::higher_order_from_side( type, elem.node_count(), 1, d, err ); MSQ_ERRRTN(err); mid = elem.get_vertex_index_array()[p]; } // If this edge contains the input vertex (vert_idx) // AND the input vertex index is less than the // other vertex (avoids iterating over this edge twice) // add it to the list. if (vert1 > vert2) { if (vert2 == vertIdx) adjList.push_back( Edge(vert1,mid) ); } else { if (vert1 == vertIdx) adjList.push_back( Edge(vert2,mid) ); } } } // Remove duplicates std::sort( adjList.begin(), adjList.end() ); adjIter = std::unique( adjList.begin(), adjList.end() ); adjList.resize( adjIter - adjList.begin() ); adjIter = adjList.begin(); }
void MeshImplData::reset_element( size_t index, const std::vector<size_t>& vertices, EntityTopology topology, MsqError& err ) { clear_element( index, err ); MSQ_ERRRTN(err); set_element( index, vertices, topology, err ); MSQ_ERRRTN(err); }
void VertexMover::initialize_queue( Mesh* mesh, MeshDomain* domain, Settings* settings, MsqError& err ) { QualityImprover::initialize_queue( mesh, domain, settings, err ); MSQ_ERRRTN(err); objFuncEval.initialize_queue( mesh, domain, settings, err ); MSQ_ERRRTN(err); }
// Create patch containing one ideal element, optionally higher-order. // For 2D elements, will attach appropriate planar domain. inline void create_ideal_element_patch( PatchData& pd, EntityTopology type, size_t num_nodes, MsqError& err ) { static PlanarDomain zplane(PlanarDomain::XY); static Settings settings; settings.set_slaved_ho_node_mode( Settings::SLAVE_NONE ); pd.attach_settings( &settings ); // build list of vertex coordinates const Vector3D* corners = unit_edge_element( type ); std::vector<Vector3D> coords( corners, corners+TopologyInfo::corners(type) ); bool mids[4] = {false}; TopologyInfo::higher_order( type, num_nodes, mids[1], mids[2], mids[3], err ); MSQ_ERRRTN(err); std::vector<size_t> conn(coords.size()); for (unsigned i = 0; i < coords.size(); ++i) conn[i] = i; for (unsigned dim = 1; dim <= TopologyInfo::dimension(type); ++dim) { if (!mids[dim]) continue; int num_side; if (dim == TopologyInfo::dimension(type)) num_side = 1; else num_side = TopologyInfo::adjacent( type, dim ); for (int s = 0; s < num_side; ++s) { unsigned idx = TopologyInfo::higher_order_from_side( type, num_nodes, dim, s, err ); MSQ_ERRRTN(err); conn.push_back(idx); unsigned n; const unsigned* side = TopologyInfo::side_vertices( type, dim, s, n, err ); MSQ_ERRRTN(err); Vector3D avg = coords[side[0]]; for (unsigned v = 1; v < n; ++v) avg += coords[side[v]]; avg *= 1.0/n; coords.push_back(avg); } } bool* fixed = new bool[coords.size()]; std::fill( fixed, fixed+coords.size(), false ); pd.fill( coords.size(), coords[0].to_array(), 1, &type, &num_nodes, &conn[0], fixed, err ); delete [] fixed; MSQ_ERRRTN(err); if (TopologyInfo::dimension(type) == 2) pd.set_domain( &zplane ); }
void TMPQualityMetric::initialize_queue( MeshDomainAssoc* mesh_and_domain, const Settings* settings, MsqError& err ) { targetCalc->initialize_queue( mesh_and_domain, settings, err ); MSQ_ERRRTN(err); if (weightCalc) { weightCalc->initialize_queue( mesh_and_domain, settings, err ); MSQ_ERRRTN(err); } }
void AddQualityMetric::get_evaluations( PatchData& pd, std::vector<size_t>& handles, bool free_only, MsqError& err ) { metric1.get_evaluations( pd, handles, free_only, err ); MSQ_ERRRTN(err); metric2.get_evaluations( pd, mHandles, free_only, err ); MSQ_ERRRTN(err); if (handles != mHandles) { MSQ_SETERR(err)("Incompatible metrics", MsqError::INVALID_STATE); } }
void TagVertexMesh::initialize( Mesh* mesh, std::string name, MsqError& err ) { MeshDecorator::set_mesh( mesh ); tagName = name; tagHandle = get_mesh()->tag_get( tagName, err ); // If tag isn't defined yet, we're done for now. if (err.error_code() == MsqError::TAG_NOT_FOUND) { err.clear(); return; } else if (MSQ_CHKERR(err)) return; // If tag is already defined, make sure it is the correct type. std::string t_name; Mesh::TagType type; unsigned length; tag_properties( tagHandle, t_name, type, length, err ); MSQ_ERRRTN(err); if (!(type == Mesh::DOUBLE && length == 3) && !(type == Mesh::BYTE && length == 3*sizeof(double))) MSQ_SETERR(err)(MsqError::TAG_ALREADY_EXISTS, "Tag \"%s\" has invalid type or size.", tagName.c_str()); // If tag is already defined and init was true, reset tag // values. haveTagHandle = true; }
void MappingFunction3D::ideal( Sample location, MsqMatrix<3,3>& J, MsqError& err ) const { const Vector3D* coords = unit_element( element_topology(), true ); if (!coords) { MSQ_SETERR(err)(MsqError::UNSUPPORTED_ELEMENT); return; } const unsigned MAX_VERTS = 8; MsqVector<3> d_coeff_d_xi[MAX_VERTS]; size_t indices[MAX_VERTS], num_vtx = 0; derivatives( location, NodeSet(), indices, d_coeff_d_xi, num_vtx, err ); MSQ_ERRRTN(err); assert(num_vtx > 0 && num_vtx <= MAX_VERTS); J.zero(); for (size_t r = 0; r < num_vtx; ++r) { MsqMatrix<3,1> c( coords[indices[r]].to_array() ); J += c * transpose(d_coeff_d_xi[r]); } double size = Mesquite::cbrt(fabs(det(J))); assert(size > -1e-15); // no negative jacobians for ideal elements! divide( 1.0, size, size ); J *= size; }
void ObjectiveFunctionTemplate::initialize_queue( Mesh* mesh, MeshDomain* domain, const Settings* settings, MsqError& err ) { qualityMetric->initialize_queue( mesh, domain, settings, err ); MSQ_ERRRTN(err); }
NonGradient::NonGradient(ObjectiveFunction* of, MsqError &err) : VertexMover(of), PatchSetUser(true), projectGradient(false), mDimension(0), mThreshold(0.0), mTolerance(0.0), mMaxNumEval(0), mNonGradDebug(0), mUseExactPenaltyFunction(true), mScaleDiameter(0.1) { set_debugging_level(2); //set the default inner termination criterion TerminationCriterion* default_crit=get_inner_termination_criterion(); if(default_crit==NULL){ MSQ_SETERR(err)("QualityImprover did not create a default inner " "termination criterion.", MsqError::INVALID_STATE); return; } else{ default_crit->add_iteration_limit( 5 ); MSQ_ERRRTN(err); } }
void TagVertexMesh::vertex_set_coordinates( VertexHandle vertex, const Vector3D &coordinates, MsqError &err ) { if (!haveTagHandle) { tagHandle = get_mesh()->tag_create( tagName, Mesh::DOUBLE, 3, 0, err ); MSQ_ERRRTN(err); haveTagHandle = true; copy_all_coordinates( err ); MSQ_ERRRTN(err); } get_mesh()->tag_set_vertex_data( tagHandle, 1, &vertex, coordinates.to_array(), err ); MSQ_ERRRTN(err); }
void TMPQualityMetric::weight( PatchData& pd, Sample sample, size_t elem, int num_idx, double& value, Vector3D* grad, SymMatrix3D* diag, Matrix3D* hess, MsqError& err ) { if (!weightCalc) return; double ck = weightCalc->get_weight( pd, elem, sample, err ); MSQ_ERRRTN(err); value *= ck; if (grad) { for (int i = 0; i < num_idx; ++i) grad[i] *= ck; } if (diag) { for (int i = 0; i < num_idx; ++i) diag[i] *= ck; } if (hess) { const int n = num_idx * (num_idx+1) / 2; for (int i = 0; i < n; ++i) hess[i] *= ck; } }
void TagVertexMesh::check_remove_tag( MsqError& err ) { if (cleanUpTag && haveTagHandle) { tag_delete( tagHandle, err ); MSQ_ERRRTN(err); } haveTagHandle = false; }
/*! */ void I_DFT_NoBarrierSmoother::optimize_vertex_positions(PatchData &pd, MsqError &err) { MSQ_FUNCTION_TIMER( "I_DFT_NoBarrierSmoother::optimize_vertex_positions" ); // does the I_DFT_NoBarrier smoothing MsqFreeVertexIndexIterator free_iter(pd, err); MSQ_ERRRTN(err); free_iter.reset(); free_iter.next(); //m is the free vertex. size_t m=free_iter.value(); //move vertex m i_dft_no_barrier_smooth_mesh(pd, m, err); MSQ_ERRRTN(err); //snap vertex m to domain pd.snap_vertex_to_domain(m,err); }
void PaverMinEdgeLengthWrapper::run_wrapper( Mesh* mesh, ParallelMesh* pmesh, MeshDomain* domain, Settings* settings, QualityAssessor* qa, MsqError& err ) { InstructionQueue q; // calculate average lambda for mesh ReferenceMesh ref_mesh( mesh ); RefMeshTargetCalculator W_0( &ref_mesh ); SimpleStats lambda_stats; MeshUtil tool(mesh, settings); tool.lambda_distribution( lambda_stats, err ); MSQ_ERRRTN(err); double lambda = lambda_stats.average(); // create objective function IdealShapeTarget W_i; LambdaConstant W( lambda, &W_i ); TShapeSizeB1 tm; TQualityMetric mu_0( &W, &tm ); ElementPMeanP mu( 1.0, &mu_0 ); PMeanPTemplate of( 1.0, &mu ); // create quality assessor EdgeLengthMetric len(0.0); qa->add_quality_assessment( &mu ); qa->add_quality_assessment( &len ); q.add_quality_assessor( qa, err ); // create solver TrustRegion solver( &of ); TerminationCriterion tc, ptc; tc.add_absolute_vertex_movement( maxVtxMovement ); tc.add_iteration_limit( iterationLimit ); ptc.add_iteration_limit( pmesh ? parallelIterations : 1 ); solver.set_inner_termination_criterion( &tc ); solver.set_outer_termination_criterion( &ptc ); q.set_master_quality_improver( &solver, err ); MSQ_ERRRTN(err); q.add_quality_assessor( qa, err ); // Optimize mesh q.run_common( mesh, pmesh, domain, settings, err ); MSQ_CHKERR(err); }
/*! \brief increment the coordinates of the index-th vertex in the raw array */ inline void PatchData::move_vertex( const Vector3D &delta, size_t index, MsqError &err) { if (index >= vertexArray.size()) { MSQ_SETERR(err)( "Index bigger than numVertices.", MsqError::INVALID_ARG ); return; } vertexArray[index] += delta; if (numSlaveVertices) { size_t num_elem; const size_t *indices; indices = get_vertex_element_adjacencies( index, num_elem, err ); MSQ_ERRRTN(err); update_slave_node_coordinates( indices, num_elem, err ); MSQ_ERRRTN(err); } }
void TerminationCriterion::reset_patch(PatchData &pd, MsqError &err) { const unsigned long totalFlag = terminationCriterionFlag | cullingMethodFlag; if (totalFlag & MOVEMENT_FLAGS) { if (previousVerticesMemento) pd.recreate_vertices_memento(previousVerticesMemento,err); else previousVerticesMemento = pd.create_vertices_memento(err); MSQ_ERRRTN(err); } if (totalFlag & UNTANGLED_MESH) { patchInvertedCount = count_inverted( pd, err ); //MSQ_DBGOUT_P0_ONLY(debugLevel) << par_string() << " o Num Patch Inverted: " << " " << patchInvertedCount << std::endl; MSQ_ERRRTN(err); } }
void GlobalPatch::get_patch( PatchHandle patch_handle, std::vector<Mesh::ElementHandle>& elem_handles_out, std::vector<Mesh::VertexHandle>& free_vertices_out, MsqError& err ) { free_vertices_out.clear(); assert(GLOBAL_PATCH_HANDLE == patch_handle); get_mesh()->get_all_elements( elem_handles_out, err ); MSQ_ERRRTN(err); //get_mesh()->get_all_vertices( free_vertices_out, err ); MSQ_ERRRTN(err); }
void SizeAdaptShapeWrapper::run_wrapper( Mesh* mesh, ParallelMesh* pmesh, MeshDomain* domain, Settings* settings, QualityAssessor* qa, MsqError& err ) { InstructionQueue q; // calculate average lambda for mesh TagVertexMesh init_mesh( err, mesh ); MSQ_ERRRTN(err); ReferenceMesh ref_mesh( &init_mesh ); RefMeshTargetCalculator W_0( &ref_mesh ); q.add_tag_vertex_mesh( &init_mesh, err ); MSQ_ERRRTN(err); // create objective function IdealShapeTarget W_i; LambdaTarget W( &W_0, &W_i ); Target2DShapeSizeBarrier tm2; Target3DShapeSizeBarrier tm3; TMPQualityMetric mu( &W, &tm2, &tm3 ); PMeanPTemplate of( 1.0, &mu ); // create quality assessor EdgeLengthMetric len(0.0); qa->add_quality_assessment( &mu ); qa->add_quality_assessment( &len ); q.add_quality_assessor( qa, err ); // create solver TrustRegion solver( &of ); TerminationCriterion tc, ptc; tc.add_absolute_vertex_movement( maxVtxMovement ); tc.add_iteration_limit( iterationLimit ); ptc.add_iteration_limit( pmesh ? parallelIterations : 1 ); solver.set_inner_termination_criterion( &tc ); solver.set_outer_termination_criterion( &ptc ); q.set_master_quality_improver( &solver, err ); MSQ_ERRRTN(err); q.add_quality_assessor( qa, err ); // Optimize mesh q.run_common( mesh, pmesh, domain, settings, err ); MSQ_CHKERR(err); }
/*! Writes a gnuplot file directly from the MeshSet. This means that any mesh imported successfully into Mesquite can be outputed in gnuplot format. Within gnuplot, use \b plot 'file1.gpt' w l, 'file2.gpt' w l This is not geared for performance, since it has to load a global Patch from the mesh to write a mesh file. */ void MeshSet::write_gnuplot(const char* out_filebase, Mesquite::MsqError &err) { // Open the file string out_filename = out_filebase; out_filename += ".gpt"; ofstream file(out_filename.c_str()); if (!file) { MSQ_SETERR(err)(MsqError::FILE_ACCESS); return; } // loads a global patch PatchData pd; PatchDataParameters pd_params; pd_params.set_patch_type(PatchData::GLOBAL_PATCH, err); MSQ_ERRRTN(err); pd_params.no_culling_method(); get_next_patch(pd, pd_params, err); MSQ_ERRRTN(err); // Write a header file << "\n"; for (size_t i=0; i<pd.num_elements(); ++i) { std::vector<size_t> vtx_indices; pd.elementArray[i].get_node_indices(vtx_indices); for (size_t j = 0; j < vtx_indices.size(); ++j) { file << pd.vertexArray[vtx_indices[j]][0] << ' ' << pd.vertexArray[vtx_indices[j]][1] << ' ' << pd.vertexArray[vtx_indices[j]][2] << '\n'; } file << pd.vertexArray[vtx_indices[0]][0] << ' ' << pd.vertexArray[vtx_indices[0]][1] << ' ' << pd.vertexArray[vtx_indices[0]][2] << '\n'; file << '\n'; } // Close the file file.close(); }
void TerminationCriterion::accumulate_patch( PatchData& pd, MsqError& err ) { if (terminationCriterionFlag & MOVEMENT_FLAGS) { double patch_max_dist = pd.get_max_vertex_movement_squared( previousVerticesMemento, err ); if (patch_max_dist > maxSquaredMovement) maxSquaredMovement = patch_max_dist; pd.recreate_vertices_memento( previousVerticesMemento, err ); MSQ_ERRRTN(err); } //if terminating on bounded vertex movement (a bounding box for the mesh) if(terminationCriterionFlag & BOUNDED_VERTEX_MOVEMENT) { const MsqVertex* vert = pd.get_vertex_array(err); int num_vert = pd.num_free_vertices(); int i=0; //for each vertex for(i=0;i<num_vert;++i) { //if any of the coordinates are greater than eps if( (vert[i][0]>boundedVertexMovementEps) || (vert[i][1]>boundedVertexMovementEps) || (vert[i][2]>boundedVertexMovementEps) ) { ++vertexMovementExceedsBound; } } } if ((terminationCriterionFlag|cullingMethodFlag) & UNTANGLED_MESH) { size_t new_count = count_inverted( pd, err ); // be careful here because size_t is unsigned globalInvertedCount += new_count; globalInvertedCount -= patchInvertedCount; patchInvertedCount = new_count; //if (innerOuterType==TYPE_OUTER) // MSQ_DBGOUT_P0_ONLY(debugLevel) << par_string() << " o Num Patch Inverted: " << " " << patchInvertedCount << " globalInvertedCount= " << globalInvertedCount << std::endl; MSQ_ERRRTN(err); } }
void TerminationCriterion::accumulate_inner( PatchData& pd, double of_value, Vector3D* grad_array, MsqError& err ) { //if terminating on the norm of the gradient //currentGradL2NormSquared = HUGE_VAL; if (terminationCriterionFlag & (GRADIENT_L2_NORM_ABSOLUTE | GRADIENT_L2_NORM_RELATIVE)) { currentGradL2NormSquared = length_squared(grad_array, pd.num_free_vertices()); // get the L2 norm MSQ_DBGOUT_P0_ONLY(debugLevel) << par_string() << " o Info -- gradient L2 norm: " << " " << RPM(std::sqrt(currentGradL2NormSquared)) << std::endl; } //currentGradInfNorm = 10e6; if (terminationCriterionFlag & (GRADIENT_INF_NORM_ABSOLUTE | GRADIENT_INF_NORM_RELATIVE)) { currentGradInfNorm = Linf(grad_array, pd.num_free_vertices()); // get the Linf norm MSQ_DBGOUT_P0_ONLY(debugLevel) << par_string() << " o Info -- gradient Inf norm: " << " " << RPM(currentGradInfNorm) << std::endl; } if (terminationCriterionFlag & VERTEX_MOVEMENT_RELATIVE) { maxSquaredInitialMovement = pd.get_max_vertex_movement_squared( initialVerticesMemento, err ); MSQ_ERRRTN(err); MSQ_DBGOUT_P0_ONLY(debugLevel) << par_string() << " o Info -- max initial vertex movement: " << " " << RPM(maxSquaredInitialMovement) << std::endl; } previousOFValue = currentOFValue; currentOFValue = of_value; if (terminationCriterionFlag & OF_FLAGS) { MSQ_DBGOUT_P0_ONLY(debugLevel) << par_string() << " o Info -- OF Value: " << " " << RPM(of_value) << " iterationCounter= " << iterationCounter << std::endl; } else if (grad_array) { MSQ_DBGOUT_P0_ONLY(debugLevel) << par_string() << " o OF Value: " << " " << RPM(of_value) << " iterationCounter= " << iterationCounter //<< " terminationCriterionFlag= " << terminationCriterionFlag << " OF_FLAGS = " << OF_FLAGS << std::endl; } ++iterationCounter; if (timeStepFileType) write_timestep( pd, grad_array, err); if (plotFile.is_open()) plotFile << iterationCounter << '\t' << mTimer.since_birth() << '\t' << of_value << '\t' << std::sqrt( currentGradL2NormSquared ) << '\t' << currentGradInfNorm << '\t' << (maxSquaredMovement > 0.0 ? std::sqrt( maxSquaredMovement ) : 0.0) << '\t' << globalInvertedCount << std::endl; }
void ReferenceMesh::get_reference_vertex_coordinates( const Mesh::VertexHandle* vertices, size_t num_vertices, Vector3D* coordinates_out, MsqError& err ) { tmpStorage.resize( num_vertices ); mMesh->vertices_get_coordinates( vertices, arrptr(tmpStorage), num_vertices, err ); MSQ_ERRRTN(err); std::copy( tmpStorage.begin(), tmpStorage.end(), coordinates_out ); }
void TerminationCriterion::accumulate_outer(Mesh* mesh, MeshDomain* domain, OFEvaluator& of_eval, const Settings* settings, MsqError &err) { PatchData global_patch; if (settings) global_patch.attach_settings( settings ); //if we need to fill out the global patch data object. if ((terminationCriterionFlag & (GRAD_FLAGS|OF_FLAGS|VERTEX_MOVEMENT_RELATIVE)) || timeStepFileType) { global_patch.set_mesh( mesh ); global_patch.set_domain( domain ); global_patch.fill_global_patch( err ); MSQ_ERRRTN(err); } accumulate_inner( global_patch, of_eval, err ); MSQ_ERRRTN(err); }