volume_cache.cpp serif/backend/mfem/mapping/volume_cache.hpp serif/utils/error/errors.hpp mfem/linalg/densemat.hpp mfem/linalg/vector.hpp serif serif::mapping #include"serif/backend/mfem/mapping/volume_cache.hpp" #include"serif/utils/error/errors.hpp" #include"mfem/linalg/densemat.hpp" #include"mfem/linalg/vector.hpp" namespaceserif::mapping{ usingnamespaceutils::errors; namespace{ //Replaceallofthesewithafastserializationclassatsomepoint.Probablyinsomethinglikeaserif/serializemodule voidpack_vector(double*&destination,constmfem::Vector&vector,constintdim){ serif_ensure<SERiFErrorCode::INVALID_DIMENSION>(vector.Size()==dim,"Vectordimension{}doesnotmatchvolumemappingcachedimension{}.",vector.Size(),dim); std::copy_n(vector.HostRead(),dim,destination); destination+=dim; } voidpack_matrix(double*&destination,constmfem::DenseMatrix&matrix,constintdim){ serif_ensure<SERiFErrorCode::MATRIX_SHAPE_ERROR>(matrix.Height()==dim&&matrix.Width()==dim,"Matrixshape{}x{}doesnotmatchvolumemappingcachedimension{}.",matrix.Height(),matrix.Width(),dim); std::copy_n(matrix.HostRead(),dim*dim,destination); destination+=dim*dim; } voidunpack_vector(constdouble*&source,mfem::Vector&vector,constintdim){ vector.SetSize(dim); std::copy_n(source,dim,vector.HostWrite()); source+=dim; } voidunpack_matrix(constdouble*&source,mfem::DenseMatrix&matrix,constintdim){ matrix.SetSize(dim,dim); std::copy_n(source,dim*dim,matrix.HostWrite()); source+=dim*dim; } } voidVolumeMappingCache::set_size(constintpoint_count,constintdimension){ serif_ensure<SERiFErrorCode::INVALID_DIMENSION>(point_count>=0,"Pointcountmustbenon-negativeforvolumemappingcache.Pointcount:{}",point_count); serif_ensure<SERiFErrorCode::INVALID_DIMENSION>(dimension>0&&dimension<=3,"Invaliddimensionforvolumemappingcache.Dimension:{}",dimension); constintstride=3*dimension+4*dimension*dimension+4; m_data.resize(static_cast<std::size_t>(point_count)*stride); m_point_count=point_count; m_dimension=dimension; m_point_stride=stride; } voidVolumeMappingCache::validate_point(constintpoint)const{ serif_ensure<SERiFErrorCode::OUT_OF_RANGE_ERROR>(point>=0&&point<m_point_count,"Pointindex{}isoutofrangeforvolumemappingcachewith{}points",point,m_point_count); } constdouble*VolumeMappingCache::get_point_data(constintpoint)const{ validate_point(point); returnm_data.data()+static_cast<std::size_t>(point)*m_point_stride; } voidVolumeMappingCache::store(intpoint,VolumeMappingContext&context){ validate_point(point); double*data=m_data.data()+static_cast<std::size_t>(point)*m_point_stride; //WhatwebuildhereisaFIFOdatastructure.wepack //alltherawdatafromthemappingcontextintoasinglecontiguousarrayofdoubles. //Thisallowsustoavoidrepeatedallocationsasthevectorwillgrowtosomeappropriatesizeandthenstayroughlythere. pack_vector(data,context.mapping.reference_position,m_dimension); pack_vector(data,context.mapping.displaced_position,m_dimension); pack_vector(data,context.mapping.physical_position,m_dimension); pack_matrix(data,context.mapping.displacement_jacobian,m_dimension); pack_matrix(data,context.mapping.mapping_jacobian,m_dimension); pack_matrix(data,context.mapping.inverse_mapping_jacobian,m_dimension); pack_matrix(data,context.quadrature.J_element_to_physical_inverse,m_dimension); *data++=context.mapping.mapping_determinate; *data++=context.mapping.compactified?1.0:0.0;//itspossiblethiscouldcauseissues,havenotrunintobutwhenunpackedIworrythatexactequalitytosomedoublevaluecouldbeaproblem.Iftherearewierdissuesthismaybeaplacetolook, *data++=context.quadrature.mapping_determinate; *data=context.quadrature.physical_integration_weight; } voidVolumeMappingCache::load(intpoint,VolumeMappingContext&context)const{ constdouble*data=get_point_data(point); //FIFOdatastructuresoneedtounpackinthesameorderaswepacked. //TODO:Redothiswithsomesortoffastserializationclasssowedonotneedtoworryaboutordering unpack_vector(data,context.mapping.reference_position,m_dimension); unpack_vector(data,context.mapping.displaced_position,m_dimension); unpack_vector(data,context.mapping.physical_position,m_dimension); unpack_matrix(data,context.mapping.displacement_jacobian,m_dimension); unpack_matrix(data,context.mapping.mapping_jacobian,m_dimension); unpack_matrix(data,context.mapping.inverse_mapping_jacobian,m_dimension); unpack_matrix(data,context.quadrature.J_element_to_physical_inverse,m_dimension); context.mapping.mapping_determinate=*data++; context.mapping.compactified=*data++!=0.0;//Seecommentinstore() context.quadrature.mapping_determinate=*data++; context.quadrature.physical_integration_weight=*data; } voidVolumeMappingCache::load_inverse_jacobian(intpoint,mfem::DenseMatrix&inverse)const{ //Againthisisunsafe,andreallyshouldbereplaced.ThiswasaquickcacheschemethatsolvedthedirectissueIhad;however,itshouldbereplaced //withsomethingthathasatleastamodicumofsafetybuiltin(weareprettygoodaboutthisinotherpartsofSERiFbutitsabout8pmand //Imquitetired.... constdouble*data=get_point_data(point)+3*m_dimension+3*m_dimension*m_dimension;//skiptotheinversejacobian,thisisjustpointermath...ThinkbacktoCS-101.Dothathavethatinthefuture,arewestilllearningaboutmemorylikethisisaPDP-11? unpack_matrix(data,inverse,m_dimension); } intVolumeMappingCache::get_point_count()constnoexcept{ returnm_point_count; } intVolumeMappingCache::get_dimension()constnoexcept{ returnm_dimension; } }